与已发布的其他答案相反,您无法修改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()
and globals()
是一样的,它会起作用;在函数内部它会usually不行。
使用字典,或在对象上设置属性:
d = {}
d['xyz'] = 42
print(d['xyz'])
或者如果您愿意,可以使用一个类:
class C: pass
obj = C()
setattr(obj, 'xyz', 42)
print(obj.xyz)
Edit:
访问命名空间中不是函数的变量(因此模块、类定义、实例)通常是通过字典查找来完成的(正如 Sven 在注释中指出的那样,也有例外,例如定义了__slots__
)。函数局部变量可以针对速度进行优化,因为编译器(通常)提前知道所有名称,因此在您调用之前不存在字典locals()
.
在Python的C实现中locals()
(从函数内部调用)创建一个从局部变量的当前值初始化的普通字典。在每个函数内任意数量的调用locals()
将返回相同的字典,但每次调用locals()
将用局部变量的当前值更新它。这会给人这样的印象:对字典元素的赋值被忽略(我最初写的是这种情况)。对返回的字典中现有键的修改locals()
因此只会持续到下一次调用locals()
在同一范围内。
在 IronPython 中,事情的工作方式有点不同。任何调用的函数locals()
它内部使用字典作为局部变量,因此对局部变量的赋值会更改字典,对字典的赋值会更改变量BUT仅当您明确调用时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}
>>>
这一切都可能随时改变。唯一可以保证的是,您不能依赖于分配给返回的字典的结果locals()
.