如何在Python中动态设置局部变量(变量名是动态的)?
最佳答案
与已经发布的其他答案相反,您不能直接修改 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 在注释中指出的那样,也有异常(exception),例如定义 __slots__ 的类) )。函数局部变量可以针对速度进行优化,因为编译器(通常)提前知道所有名称,因此在调用 locals()
之前不存在字典。
在 Python 的 C 实现中,locals()
(从函数内部调用)创建一个从局部变量的当前值初始化的普通字典。在每个函数中,任意多次调用 locals()
都会返回相同的字典,但每次调用 locals()
都会使用局部变量的当前值更新它。这会给人这样的印象:对字典元素的赋值被忽略(我最初写的是这种情况)。因此,对从 locals()
返回的字典中现有键的修改只会持续到下一次在同一范围内调用 locals()
为止。
在 IronPython 中,事情的工作方式有点不同。任何在其内部调用 locals()
的函数都使用字典作为其局部变量,因此对局部变量的赋值会更改字典,对字典的赋值会更改变量但是,只有当您以该名称显式调用 locals()
。如果您将不同的名称绑定(bind)到 IronPython 中的 locals
函数,则调用它会为您提供绑定(bind)该名称的范围的局部变量,并且无法通过它访问函数局部变量:
>>> 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}
>>>
这一切都可能随时改变。唯一可以保证的是,您不能依赖 locals()
返回的字典的分配结果。
关于python - 动态设置局部变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52320393/