首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >闭包在runpy中是如何工作的?

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

Stack Overflow用户
提问于 2011-08-17 19:21:36
回答 1查看 533关注 0票数 3

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

代码语言:javascript
复制
#test.py
import runpy
env = runpy.run_path('test', {'y':'world'})
env['fn']()

~

代码语言:javascript
复制
#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的预期输出是:

代码语言:javascript
复制
 world
hello
world
 world
hello
world

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

然而,我得到的却是:

代码语言:javascript
复制
 world
hello
world
No re
None
None

看起来re没有在fn中定义,尽管它应该具有正常的闭包行为。X和y甚至更奇怪,因为它们看起来像是定义的,但实际上设置为None。

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

EN

回答 1

Stack Overflow用户

发布于 2011-08-17 20:25:55

好吧,这是对Python处理模块方式的好奇心,我知道但不完全理解。我在开发IPython时遇到过它,在a comment中解释了它。

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

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

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7092000

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档