我试图理解Python的exec()函数

我试图理解Python的exec()函数,python,python-3.x,Python,Python 3.x,我有一个字符串,它是一个函数 code = """def somefn(x): return x + x y = somefn(z)""" def otherfn(codestr): z = 2 exec(codestr) return y otherfn(code) 我试图在另一个函数中运行它,比如 code = """def somefn(x): return x + x y = somefn(z)""" def otherfn

我有一个字符串,它是一个函数

code = """def somefn(x):
    return x + x
    y = somefn(z)"""
def otherfn(codestr):
    z = 2
    exec(codestr)
    return y

otherfn(code)
我试图在另一个函数中运行它,比如

code = """def somefn(x):
    return x + x
    y = somefn(z)"""
def otherfn(codestr):
    z = 2
    exec(codestr)
    return y

otherfn(code)
但它给了我一个错误:

回溯最近一次呼叫上次: 文件C:/Users/Admin/Desktop/heh.py,第11行,在 其他FNcode 文件C:/Users/Admin/Desktop/heh.py,第9行,在otherfn中 返回y 名称错误:未定义名称“y”

它在函数之外工作良好,如

code = """def somefn(x):
    return x + x
    y = somefn(z)"""
def otherfn(codestr):
    z = 2
    exec(codestr)
    return y

otherfn(code)
z=2 execcodestr 普林蒂

它发现y很好,但不确定它在函数中时为什么会出错


我怎样才能解决这个问题?这与全球人和本地人有关吗?顺便说一句,使用Python 3.6时,您的代码有几个问题。首先,您有一个缩进问题—y在somefn函数中得到“定义”,在返回之后,因此它实际上没有机会进入堆栈。您需要将代码重新定义为:

但这只是冰山一角。更大的问题是exec无法修改函数的本地范围。这是因为Python不使用dict来查找本地范围内的变量,因此exec的所有更改不会反射回堆栈以启用查找。这导致了一个奇怪的问题,exec似乎更改了本地词典,但Python仍然抛出一个名称错误:

这是一种预期行为,如中所述,并在中进一步说明:

注意:默认局部变量的作用如下所述:不应尝试修改默认局部变量字典。如果需要在函数返回后查看代码对局部变量的影响,请传递显式局部变量字典

但是,如果必须反映这些更改,则只需执行post exec本地范围更新:

def otherfn(codestr):
    z = 2
    locals_ = locals()
    exec(codestr, globals(), locals_)
    y = locals_["y"]
    return y

otherfn(code)