简体   繁体   English

我正在尝试了解Python的exec()函数

[英]I'm trying to understand Python's exec() function

So I have a string which is a function like 所以我有一个像这样的函数的字符串

code = """def somefn(x):
    return x + x
    y = somefn(z)"""

and I am trying to run this in another function like 我试图在另一个函数中运行它

def otherfn(codestr):
    z = 2
    exec(codestr)
    return y

otherfn(code)

but it gives me the error: 但这给了我错误:

Traceback (most recent call last): File "C:/Users/Admin/Desktop/heh.py", line 11, in otherfn(code) File "C:/Users/Admin/Desktop/heh.py", line 9, in otherfn return y NameError: name 'y' is not defined 追溯(最近一次通话最近):文件“ C:/Users/Admin/Desktop/heh.py”,第11行,在其他fn(代码)文件“ C:/Users/Admin/Desktop/heh.py”,第9行,在otherfn中返回y NameError:未定义名称'y'

it works fine outside the function like 它在功能之外工作正常

z=2 exec(codestr) print(y)

it finds y just fine but not sure why it is bugging out when it is in the function. 它发现y很好,但不确定为什么在函数中时会出现bug。

How can I fix this? 我怎样才能解决这个问题? Is it something to do with globals() and locals()? 与globals()和locals()有关吗? Using Python 3.6 btw. 使用Python 3.6 btw。

There are several problems with your code. 您的代码有几个问题。 First of all, you have an indentation problem - the y gets 'defined' inside the somefn() function, after the return so it never actually gets the chance to get onto the stack. 首先,您有一个缩进问题yreturn后在somefn()函数内被“定义”,因此它实际上从未有机会进入堆栈。 You need to redefine your code to : 您需要将code重新定义为:

code = """def somefn(x):
    return x + x
y = somefn(z)"""

But that's just the tip of the iceberg. 但这只是冰山一角。 The greater issue is that exec() cannot modify the local scope of a function. 更大的问题是exec()无法修改函数的局部范围。 This is due the fact that Python doesn't use a dict for lookup of variables in the local scope so all changes from the exec() do not get reflected back to the stack to enable lookup. 这是由于以下事实:Python在本地范围内不使用dict来查找变量,因此exec()所有更改都不会反映回堆栈以启用查找。 This causes a weird issue where exec() seemingly changes the locals() dictionary, but Python still throws a NameError : 这引起了一个奇怪的问题,其中exec()似乎改变了locals()字典,但是Python仍然抛出NameError

def otherfn(codestr):
    z = 2
    exec(codestr)
    print(locals()["y"])  # prints 4
    return y  # NameError

otherfn(code)

This is an intended behavior, as explained in the issue4831 , and further pontificated in the official docs : 这是预期的行为,如issue4831中所述,并在官方文档中进一步加以说明:

Note : The default locals act as described for function locals() below: modifications to the default locals dictionary should not be attempted. 注意 :默认本地语言的行为与下面对函数locals()描述相同:不应尝试对默认本地语言字典进行修改。 Pass an explicit locals dictionary if you need to see effects of the code on locals after function exec() returns. 传递一个明确的当地人解释,如果你需要看后当地人的功能代码的作用exec()的回报。

But if you have to reflect the changes you can just do a post-exec local scope update: 但是,如果您必须反映更改,则可以执行后执行本地范围更新:

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

otherfn(code)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何理解我正在尝试编写的 function 中的未定义错误 - How to understand an undefined error in a function I'm trying to write 我正在尝试了解 Python 中的二进制文件模式 - I'm trying to understand binary file mode in Python 我试图了解参考在 python 中的工作原理 - I'm trying to understand how reference works in python 我正在尝试使用 pd.read_csv() 将文件加载到 Python 中,但我无法理解文件的格式 - I'm trying to load a file into Python using pd.read_csv(), but I cannot understand the file's format 试图理解 Python Regex 的 - Trying to understand Python Regex's 试图了解python递归函数 - Trying to understand a python recursion function 我想了解递归过程吗? - I'm trying to understand the recursion process? 我正在尝试将 url 作为 function 中 flask Z23EEEB4947BDD25BDD6 - I'm trying to give url as a parameter in function in flask python but it's showing me this error 我正在尝试使用 Python 读取域名的 IP 地址,但我遇到了奇怪的错误,我不太明白 - I'm trying to read the IP address for a domain name with Python and I'm getting strange errors I don't quite understand 我正在尝试在notepad ++中设置python,但它无法理解我的文件路径中是否有空格 - I'm trying to set up python in notepad++ and it can't understand my filepath that has a space in it
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM