有没有办法在运行时影响当地人?(Is there any way to affect locals

2019-10-28 09:05发布

其实我是想创建一个新的地方。 我知道这听起来很可疑,但我觉得我有这个一个很好的使用情况。 从本质上讲我的问题是,这种代码抛出“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和调用一些保密功能它做的事,但他们只谈了更新的价值。 但也许有一个更简单的方法?

Answer 1:

由于格雷格Hewgill关于该问题的评论中提到,我回答另一个问题有关修改locals在Python 3,我会在这里给有点重述。

有一个Python的3错误列表后这个问题-这有点在Python 3手册不良记录。 Python 3中使用当地人代替字典阵列像在Python 2 - 的优点是局部变量更快的查找时间(LUA这是否太)。 基本上,该阵列是在“字节码编译时间”定义并且不能在运行时修改。

见特别是在最后一段乔治·布兰德的错误列表后的更精细的细节,为什么这不能(也许永远不会)在Python 3工作。



Answer 2:

我为你的使用情况非常好奇。 为什么地球上你想捅新的本地到调用方的框架,而不是简单地做这样的事情:

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)


Answer 3:

在Python 2 *,你可以得到这样的代码通过击败当地人的正常优化工作:

>>> def g():
...   exec 'pass'
...   f()
...   print(eggs)

一个的存在exec语句导致的Python 2编译g在一个完全非优化的方式,所以当地人在一个字典,而不是阵列中的,因为它们通常会。 (对性能的影响可能相当大)。

这种“去优化”并不在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 - 那些仍然是一个字典,毕竟。



文章来源: Is there any way to affect locals at runtime?