我其实想要创建一个新的本地。我知道这听起来很可疑,但我认为我有一个很好的用例。基本上我的问题是,当我尝试打印鸡蛋时,此代码抛出“NameError:全局名称'鸡蛋'未定义”:
def f():
import inspect
frame_who_called = inspect.stack()[1][0]
frame_who_called.f_locals['eggs'] = 123
def g():
f()
print(eggs)
g()
我发现了这件旧事: http://mail.python.org/pipermail/python-dev/2005-January/051018.html
这意味着我可以使用ctypes并调用一些秘密函数来完成它,尽管他们只讨论了更新值。但也许有一种更简单的方法?
答案 0 :(得分:3)
我对你的用例非常好奇。为什么在地球上你试图将一个新的局部戳到调用者的框架中,而不是简单地做这样的事情:
def f():
return 123
def g():
eggs = f()
print(eggs)
毕竟,你可以返回一个包含任意数量值的元组:
def f():
return 123, 456, 789
def g():
eggs, ham, bacon = f()
print(eggs, ham, bacon)
答案 1 :(得分:2)
正如Greg Hewgill在对该问题的评论中提到的那样,我回答another question关于修改Python 3中的locals
,我将在这里给出一些回顾。
关于这个问题有一个post on the Python 3 bug list - 它在Python 3手册中有些记载。 Python 3使用一个数组用于本地而不是像Python 2中那样的字典 - 优点是局部变量的查找时间更快(Lua也这样做)。基本上,数组是在“字节码 - 编译时”定义的,不能在运行时修改。
具体参见Georg Brandl's post on the bug list中的最后一段,了解为什么这不能(也可能永远不会)在Python 3中有效的详细信息。
答案 2 :(得分:1)
在Python 2. *中,你可以通过击败本地人的正常优化来获得这样的代码:
>>> def g():
... exec 'pass'
... f()
... print(eggs)
exec
语句的存在会导致Python 2以完全非优化的方式编译g
,因此本机在dict中而不是像往常一样在数组中。 (性能影响可能相当大)。
这种“去优化”在Python 3中不存在,其中exec
不再是一个语句(甚至不是一个关键字,只是一个函数) - 即使在它后面加上括号也无济于事。 ..:
>>> def x():
... exec('a=23')
... print(a)
...
>>> x()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in x
NameError: global name 'a' is not defined
>>>
即即使exec
现在也不能“创建在def
时间不知道的本地人”(即,当编译器执行其传递以将函数体转换为字节码时)。
你最好的选择就是放弃。第二好的方法是让你的f
函数在调用者globals
中注入新名称 - 那些毕竟仍然是一个字典。