Python 在runpy中闭包是如何工作的?

Python 在runpy中闭包是如何工作的?,python,closures,runpy,Python,Closures,Runpy,当我尝试运行在使用模块加载的文件中定义的方法时,会出现意外行为。这些方法看不到在该方法之外定义的任何变量(包括导入的模块)。我是这样做的: #test.py import runpy env = runpy.run_path('test', {'y':'world'}) env['fn']() ~ test.py的预期输出为: world hello world world hello world 因为fn将形成re,x和y的闭包 然而,我得到的却是: world hello worl

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

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

test.py的预期输出为:

 world
hello
world
 world
hello
world
因为fn将形成re,x和y的闭包

然而,我得到的却是:

 world
hello
world
No re
None
None
看起来似乎re没有在fn中定义,即使它应该具有正常的闭包行为。x和y更为奇怪,因为它们似乎已定义,但设置为“无”


这是为什么?闭包如何与runpy一起工作?我如何才能实现正常的行为,使fn能够“看到”外部变量?

好的,这是Python处理模块的方式,我知道但不完全理解。我在IPython的工作中遇到过这个问题,在那里有详细的解释

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

我不知道是否有办法通过
runpy
来解决这个问题。IPython使用一些复杂的代码来重用模块对象以运行其他文件,缓存其
\uuuu dict\uuu
的副本以保持其中的引用处于活动状态。如果你感兴趣的话,请看一下

 world
hello
world
No re
None
None