2

从环境(它是一个名为 nuke 的图形程序)中获得了一个全局对象,我可以在其中添加菜单项并将其与函数连接。这个全局对象的工作方式如下:

menu.addCommand("Do This!", lambda: DoThings())

我想动态读取python模块并将模块函数添加为全局菜单对象中的一个项目。我写了一个类来做到这一点。我的课程的简化版本:

class mymenu():
.
.
.
def _builMenuFromPath(self, basepath, module):

    items = []

    # ...
    # there is code to build the items list. this is a list of the python filenames
    # ...

    if len(items) > 0:

        for item in items:

            try:
                f = getattr(__import__(module + "." + item), item) # item is the python filename of an module in the folder with the python files and module is the folder

                menu.addCommand(item, lambda: f.call()) # f.call() is a function in the dynamic loaded python file

            except Exception, e:
                pass

动态导入效果很好。但是每个生成的菜单项都链接到最后一个导入的函数。这样每个菜单项都一样。

我不是专业的程序员。所以我认为我犯了一个简单的错误。

谢谢你的帮助。

4

2 回答 2

0

表达式中的问题lambda: f.call()f是一个自由术语,指的f是封闭范围内的变量。这意味着f在 lambda 中值的变化是显而易见的。例如:

>>> n = 1
>>> lambda: n
<function <lambda> at 0x00000000027F0898>
>>> l = lambda: n
>>> l()
1
>>> n = 2
>>> l()
2

但是,这lambda是不必要的,因为 python 中的函数和方法是对象,它们本身可以在任何可以传递任何可调用(如 lambda)的地方传递。在这段代码中:

menu.addCommand(item, f.call)

f.call是一个表达式,它将评估为可调用的绑定方法。

于 2012-07-10T20:45:58.580 回答
0

尝试传递 f.call 而不是 lambda:f.call()。

于 2012-07-10T20:32:38.697 回答