gpt4 book ai didi

python - execfile() 不能可靠地用于修改函数的局部变量

转载 作者:行者123 更新时间:2023-11-28 21:24:25 24 4
gpt4 key购买 nike

python 文档指出“execfile() 不能可靠地用于修改函数的局部变量。”在页面上http://docs.python.org/2/library/functions.html#execfile

任何人都可以提供有关此声明的更多详细信息吗?文档相当少。该语句似乎与“如果两个字典都被省略,则表达式在调用execfile()的环境中执行”非常矛盾。这也在文档中。如果在函数中使用 excecfile,然后 execfile 的行为类似于创建新范围级别的函数,是否存在特殊情况?

如果我在函数中使用 execfile,例如

def testfun():
execfile('thefile.py',globals())
def testfun2():
print a

还有'thefile.py'中的命令创建的对象(例如对象'a'),我怎么知道它们是testfun的局部对象还是全局对象?那么,在函数 testfun2 中,'a' 看起来是全局的?如果我从 execfile 语句中省略 globals(),谁能给出更详细的解释,为什么“thefile.py”中的命令创建的对象对“testfun”不可用?

最佳答案

在 Python 中,查找名称的方式在函数内部进行了高度优化。其中一个副作用是 locals() 返回的映射为您提供了函数内部局部名称的副本,并且更改该映射实际上不会影响函数:

def foo():
a = 'spam'
locals()['a'] = 'ham'
print(a) # prints 'spam'

在内部,Python 使用LOAD_FAST 操作码按索引 在当前帧中查找a 名称,而不是较慢的LOAD_NAME,它将查找本地名称(按名称),如果在第一个中找不到,则在 globals() 映射中查找。

Python 编译器只能为在编译时 已知的本地名称发出LOAD_FAST 操作码;但是如果您允许 locals() 直接影响函数的局部变量,那么您就无法提前知道所有局部名称。使用作用域名称(自由变量)的嵌套函数使事情变得更加复杂。

在 Python 2 中,您可以通过在函数中使用 exec 语句强制编译器关闭优化并始终使用 LOAD_NAME:

def foo():
a = 'spam'
exec 'a == a' # a noop, but just the presence of `exec` is important
locals()['a'] = 'ham'
print(a) # prints 'ham'

在 Python 3 中,exec 已被 exec() 取代,解决方法也已消失。在 Python 3 中,所有 函数都得到了优化。

如果您没有遵循所有这些,那也没关系,但这就是文档稍微掩盖这一点的原因。这都是由于大多数 Python 用户不需要了解的 CPython 编译器和解释器的实现细节;您只需要知道,使用 locals() 更改函数中的本地名称通常是行不通的。

关于python - execfile() 不能可靠地用于修改函数的局部变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16065468/

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