我有以下代码
fset = [ obj for name,obj in inspect.getmembers(sys.modules[__name__]) if inspect.isfunction(obj) ]
def func(num):
pass
if __name__ == "__main__":
print(fset)
印刷品
[]
然而
def func(num):
pass
fset = [ obj for name,obj in inspect.getmembers(sys.modules[__name__]) if inspect.isfunction(obj) ]
if __name__ == "__main__":
print(fset)
印刷品
[<function func at 0x7f35c29383b0>]
那么,fset是当前模块中所有函数的列表,其中fset是在所有函数的顶部定义的?
编辑一:我想做的是
def testall(arg):
return any(f(arg) for f in testfunctions)
def test1(arg):
#code here
# may call testall but wont call anyother test*
def test2(arg):
#code here
# may call testall but wont call anyother test*
今后可能会增加更多的测试功能。所以这就是fset/testfunctions的原因
这很管用:
在这种情况下,
testfunctions
在调用testall
之前不会求值,因此此时没有问题,所有顶级模块代码(包括test1
定义)都将求值,因此testfunctions
将获得所有顶级函数。(我假设testall
或test1
是从模块底部的if __name__ == '__main__'
块调用的,或者另一个脚本正在执行import tests; tests.test1(10)
或类似的操作。)实际上,即使您显式地命名了
test1
和test2
,也不会有问题:同样,
test1
已经在您调用testall
时定义,所以一切都很好。如果你想理解为什么这样做,你必须理解这里的阶段。
导入模块或运行顶级脚本时,第一个阶段是编译(除非已经有一个缓存的.pyc文件)。编译器不需要知道一个名称有什么值,只需要知道它是本地的还是全局的(或者是一个闭包单元格),它已经可以知道
sys
和inspect
和test1
是全局的(因为您没有在testall
或封闭的作用域中分配给它们)。接下来,解释器按顺序执行顶级模块的编译字节码。这包括执行函数定义。因此,
testall
变成一个函数,然后test1
变成一个函数,然后test2
变成一个函数。(函数实际上只是适当的编译代码,附加了一些额外的东西,比如它在中定义的全局命名空间。)稍后,当您调用
testall
函数时,解释器将执行该函数。这是当列表理解(在第一个版本中)或全局名称查找(在第二个版本中)发生时。由于test1
和test2
的函数定义已经被求值并绑定到模块中的全局名称,所以一切正常。如果您稍后调用
test1
,它调用testall
,会怎么样?没问题。解释器执行test1
,它有一个对testall
的调用,这个调用显然已经定义好了,所以解释器调用它,剩下的与前面的段落相同。那么,如果在
test1
和test2
定义之间调用testall
或test1
呢?在这种情况下,test2
还没有定义,因此它不会出现在列表中(第一个版本),或者引发一个NameError
(第二个版本)。但只要你不这么做,就没问题。也没有理由这么做。如果你担心每次你打电话给
testall
时计算的可怕性能成本……那么,首先,这是一个愚蠢的担心;你要打多少次电话?你的函数真的如此之快以至于调用和过滤的时间甚至出现在雷达上了吗?但如果真的很担心,只需将值缓存到您最喜欢的可变默认值、privat global、function attribute、…:不可能。函数定义在Python中执行。这些函数在执行其定义之前不存在。在定义函数之前,无法定义
fset
变量。相关问题 更多 >
编程相关推荐