嵌套函数的名称是什么?为什么eval没有看到嵌套函数?

时间:2018-10-24 22:52:11

标签: python scope namespaces eval

当我尝试运行此代码时,出现以下错误。我正在尝试使用函数指针初始化列表。看来eval没有看到功能。我猜测正在发生某种我不了解的范围界定。如您所见,当我手动创建表时,它可以工作。我试图避免必须维护功能列表。当我将函数设为全局时,这也起作用。

 Traceback (most recent call last):
   File "/home/westgate/code/python/try/x.py", line 27, in <module>
     main()
   File "/home/westgate/code/python/try/x.py", line 23, in main
     fxns_eval = [eval(fxn_name) for fxn_name in dir() if fxn_name.startswith('fxn_')]
   File "/home/westgate/code/python/try/x.py", line 23, in <listcomp>
     fxns_eval = [eval(fxn_name) for fxn_name in dir() if fxn_name.startswith('fxn_')]
   File "<string>", line 1, in <module>
 NameError: name 'fxn_bar' is not defined

import inspect

def main():

    def fxn_foo():
        print('in foo '+inspect.currentframe().f_code.co_name)

    def fxn_bar():
        print('in bar '+inspect.currentframe().f_code.co_name)

    for i in dir():
        if i.startswith('fxn_'):
            print(i)

    fxn_bar()

    fxns = [ fxn_foo, fxn_bar ]

    fxns[1]()

    fxns_eval = [eval(fxn_name) for fxn_name in dir() if fxn_name.startswith('fxn_')]

    fxns_eval[1]()

main()

1 个答案:

答案 0 :(得分:2)

问题是您没有显式传递locals,所以。来自docs

  

如果两个字典都省略了,则在   调用eval()的环境。

但是,环境是列表理解,它创建了它自己的作用域,并且这些功能都不在列表理解的本地名称空间或全局名称空间中。您需要 main的本地名称空间所以请注意,这可行:

>>> def main():
...    def foo(): 'foo'
...    print(eval('foo'))
...
>>> main()
<function main.<locals>.foo at 0x10c3ba6a8>

显式传递globalslocals()但是,您必须将它们用作列表理解范围的自由变量,因为它本质上就像另一个嵌套函数范围,您也不能这样做:

>>> def main():
...    def foo(): 'foo'
...    def bar(): 'bar'
...    print([eval(x, globals(), locals()) for x in dir()])
...
>>> main()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in main
  File "<stdin>", line 4, in <listcomp>
  File "<string>", line 1, in <module>
NameError: name 'bar' is not defined

实际上,等同于完全不传递参数

您可以这样做:

>>> def main():
...    def foo(): 'foo'
...    def bar(): 'bar'
...    locs, globs = locals(), globals()
...    print([eval(x, globs, locs) for x in dir()])
...
>>> main()
[<function main.<locals>.bar at 0x10bded1e0>, <function main.<locals>.foo at 0x10c3ba6a8>, {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'n1': 1014.308, 'n0': 961.06, 'p1': 18.59, 'p0': 19.65, 'q1': 1014.308, 'q0': 961.06, 'main': <function main at 0x10c3ba620>}, {'foo': <function main.<locals>.foo at 0x10c3ba6a8>, 'bar': <function main.<locals>.bar at 0x10bded1e0>, 'globs': {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'n1': 1014.308, 'n0': 961.06, 'p1': 18.59, 'p0': 19.65, 'q1': 1014.308, 'q0': 961.06, 'main': <function main at 0x10c3ba620>}, 'locs': {...}}]
>>>