一尘不染

Python-动态设置局部变量

python

如何在Python中动态设置局部变量(变量名是动态的)?


阅读 747

收藏
2020-02-15

共1个答案

一尘不染

与已经发布的其他答案相反,你不能locals()直接修改并期望它可以正常工作。

>>> def foo():
    lcl = locals()
    lcl['xyz'] = 42
    print(xyz)


>>> foo()

Traceback (most recent call last):
  File "<pyshell#6>", line 1, in <module>
    foo()
  File "<pyshell#5>", line 4, in foo
    print(xyz)
NameError: global name 'xyz' is not defined

修改locals()未定义。在函数外部,当locals()globals()相同时,它将起作用;在一个函数内部通常将不起作用。

使用字典,或在对象上设置属性:

d = {}
d['xyz'] = 42
print(d['xyz'])

或者,如果你愿意,可以使用一个类:

class C: pass

obj = C()
setattr(obj, 'xyz', 42)
print(obj.xyz)

编辑:访问不是函数的名称空间中的变量(因此,模块,类定义,实例)通常是通过字典查找来完成的(如Sven在注释中指出的那样,有一些例外,例如define的类__slots__)。可以优化函数局部变量的速度,因为编译器(通常)会事先知道所有名称,因此在你调用之前没有字典locals()。

在Python的C实现中locals()(从函数内部调用),从局部变量的当前值初始化一个普通的字典。在每个函数中,任意数量的调用locals()都会返回相同的字典,但是每次调用locals()都会使用局部变量的当前值对其进行更新。这给人的印象是字典元素的赋值被忽略了(我最初是这样写的)。locals()因此,从返回的字典中对现有键的修改仅持续到locals()同一范围内的下一次调用为止。

在IronPython中,工作原理有所不同。该调用的任何函数locals()内部它采用了字典局部变量赋值使局部变量改变词典和分配到字典改变的变量,但,这只是如果你显式调用locals()那个名字。如果locals在IronPython 中将不同的名称绑定到函数,则调用该函数将为你提供绑定该名称的作用域的局部变量,并且无法通过它访问函数的局部变量:

>>> def foo():
...     abc = 123
...     lcl = zzz()
...     lcl['abc'] = 456
...     deF = 789
...     print(abc)
...     print(zzz())
...     print(lcl)
...
>>> zzz =locals
>>> foo()
123
{'__doc__': None, '__builtins__': <module '__builtin__' (built-in)>, 'zzz': <built-in function locals>, 'foo': <function foo at 0x000000000000002B>, '__name__': '__main__', 'abc': 456}
{'__doc__': None, '__builtins__': <module '__builtin__' (built-in)>, 'zzz': <built-in function locals>, 'foo': <function foo at 0x000000000000002B>, '__name__': '__main__', 'abc': 456}
>>>
2020-02-15