闭包如何在运行中工作?
作者:互联网
当我尝试运行在使用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