gpt4 book ai didi

python - 闭包如何在 runpy 中工作?

转载 作者:太空宇宙 更新时间:2023-11-03 15:25:51 25 4
gpt4 key购买 nike

当我尝试运行在使用 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运行一个模块时,它会产生一个模块对象,其属性是模块中的全局名称。当模块超出范围并被销毁时,这些属性将设置为 None。正如您所发现的,在函数中定义的代码然后将这些视为全局变量。您可以通过将 def g(): return globals() 添加到您的文件,然后调用 env["g"]() 来证明这一点。

我不知道是否有办法使用 runpy 解决这个问题。 IPython 使用一些复杂的代码来重用模块对象来运行其他文件,缓存其 __dict__ 的副本以保持其中的引用处于事件状态。看看 magic_run function如果你有兴趣。

关于python - 闭包如何在 runpy 中工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7092000/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com