其他分享
首页 > 其他分享> > 闭包如何在运行中工作?

闭包如何在运行中工作?

作者:互联网

当我尝试运行在使用runpy模块加载的文件中定义的方法时,出现意外行为.这些方法看不到在该方法之外定义的任何变量(包括导入的模块).这是我的做法:

#test.py
import runpy
env = runpy.run_path('test', {'y':'world'})
env['fn']()

#test
import re

print(re.compile(r'^hello', re.IGNORECASE).sub('', "hello world"))
x = "hello"
print(x)
print(y)

def fn():
    try:
        print(re.compile(r'^hello', re.IGNORECASE).sub('', "hello world"))
    except:
        print("No re")
    try:
        print(x)
    except:
        print("No x")
    try:
        print(y)
    except:
        print("No y")

我的test.py预期输出为:

 world
hello
world
 world
hello
world

因为fn会形成re,x和y的闭包.

但是,相反,我得到:

 world
hello
world
No re
None
None

看起来re并未在fn中定义,即使它应该具有正常的关闭行为. x和y甚至更陌生,因为它们似乎已定义但设置为None.

为什么会这样?闭包如何与runpy一起使用?我如何才能实现正常行为,以便fn可以“看到”外部变量?

解决方法:

好的,这是对Python处理模块的好奇心,我了解但还不完全了解.我在IPython上工作时遇到过它,它在a comment中进行了解释.

当Python运行模块时,它会生成一个模块对象,其属性是模块中的全局名称.当模块超出范围并被销毁时,这些属性将设置为“无”.如您所见,在函数中定义的代码随后将其视为全局变量.您可以通过添加def g()来证明这一点:将globals()返回到文件中,然后调用env [“ g”]().

我不知道有没有办法解决运行问题. IPython使用一些复杂的代码重用模块对象来运行其他文件,并缓存其__dict__的副本以使其中的引用保持活动状态.如果您有兴趣的话,看看magic_run function.

标签:closures,python,runpy
来源: https://codeday.me/bug/20191102/1990355.html