gpt4 book ai didi

python - 在 Python 3 中使用在 exec'ed 字符串中定义的函数

转载 作者:IT老高 更新时间:2023-10-28 20:46:38 26 4
gpt4 key购买 nike

为什么下面的python3代码会报错?

a='''
def x():
print(42)
'''

class Test:
def __init__(self):
exec(a)
x()

t = Test()

此消息中的结果:

Traceback (most recent call last):
File "bug.py", line 11, in <module>
t = Test()
File "bug.py", line 9, in __init__
x()
NameError: global name 'x' is not defined

最佳答案

注意:exec 在 Python 2.x 中只是一个简单的语句,而在 Python 3.x 中它是一个函数。

Python 2.7

让我们检查通过执行 a 所做的更改。

class Test:
def __init__(self):
l, g = locals().copy(), globals().copy()
exec a # NOT a function call but a statement
print locals() == l, globals() == g
x()

t = Test()

输出

False True
42

这意味着,它改变了 locals 字典中的某些内容。如果你在 exec 之前和之后打印 locals().keys(),你会看到 x,在 exec 之后>。根据 exex 的文档,

In all cases, if the optional parts are omitted, the code is executed in the current scope.

因此,它完全按照文档中的说明进行操作。

Python 3.x:

当我们在 Python 3.x 中执行相同的操作时,我们会得到类似的结果,除了我们得到那个错误。

class Test:
def __init__(self):
l, g = locals().copy(), globals().copy()
exec(a) # Function call, NOT a statement
print(locals() == l, globals() == g)
x()

输出

False True
NameError: name 'x' is not defined

即使是 documentation of exec function说,

In all cases, if the optional parts are omitted, the code is executed in the current scope.

但它还在底部包含一个注释,

Note: The default locals act as described for function locals() below: modifications to the default locals dictionary should not be attempted. Pass an explicit locals dictionary if you need to see effects of the code on locals after function exec() returns.

所以,我们好奇地检查了locals() documentation并找到

Note: The contents of this dictionary should not be modified; changes may not affect the values of local and free variables used by the interpreter.

因此,解释器不支持对 locals() 对象所做的更改。这就是为什么它无法识别本地范围中定义的 x

但是当我们这样做时

def __init__(self):
exec(a, globals())
x()

它有效,因为我们将它添加到 globals 字典中。 Python 尝试首先在本地范围内查找 x,然后在类范围内,然后在全局范围内查找,并在那里找到它。所以它执行它没有任何问题。

关于python - 在 Python 3 中使用在 exec'ed 字符串中定义的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24733831/

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