Dun*_*can 71
与已发布的其他答案相反,您无法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
Run Code Online (Sandbox Code Playgroud)
修改locals()未定义.外部的功能时locals(),并globals()在它的工作是相同的; 在函数内部它通常不起作用.
使用字典,或在对象上设置属性:
d = {}
d['xyz'] = 42
print(d['xyz'])
Run Code Online (Sandbox Code Playgroud)
或者如果您愿意,可以使用课程:
class C: pass
obj = C()
setattr(obj, 'xyz', 42)
print(obj.xyz)
Run Code Online (Sandbox Code Playgroud)
编辑:访问不是函数的命名空间中的变量(所以模块,类定义,实例)通常通过字典查找来完成(正如Sven在注释中指出的那样有异常,例如定义的类__slots__).函数本地可以针对速度进行优化,因为编译器(通常)预先知道所有名称,因此在调用之前不会有字典locals().
在Python的C实现中locals()(从函数内部调用)创建一个从局部变量的当前值初始化的普通字典.在每个函数中,任何数量的调用都locals()将返回相同的字典,但每次调用locals()都会使用局部变量的当前值更新它.这可能会给人一种印象,即对字典元素的赋值会被忽略(我原来写的就是这种情况).locals()因此,对返回的字典中现有键的修改仅持续到下一次调用locals()同一范围内.
在IronPython中,事情有点不同.locals()在其中调用的任何函数都使用字典作为其局部变量,因此对局部变量的赋值会更改字典,并且对字典的赋值会更改变量但仅当您locals()在该名称下显式调用时才会更改.如果你将一个不同的名字绑定到localsIronPython中的函数,那么调用它会为你提供绑定名称的范围的局部变量,并且无法通过它访问函数locals:
>>> 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}
>>>
Run Code Online (Sandbox Code Playgroud)
这一切都可以随时改变.唯一保证的是你不能依赖于分配给返回的字典的结果locals().
kin*_*all 25
其他人建议分配给locals().这在使用LOAD_FAST操作码访问本地的函数内部不起作用,除非exec函数中有某个语句.为了支持这个语句,它可以创建在编译时未知的新变量,然后Python被强制在函数中按名称访问局部变量,所以写入locals()工作.所述exec可以出所执行的代码路径的.
def func(varname):
locals()[varname] = 42
return answer # only works if we passed in "answer" for varname
exec "" # never executed
func("answer")
>>> 42
Run Code Online (Sandbox Code Playgroud)
注意:这仅适用于Python 2.x. 他们在Python 3中摒弃了这种愚蠢,其他实现(Jython,IronPython等)也可能不支持它.
不过,这是一个坏主意.如果您不知道他们的名字,您将如何访问变量?通过locals()[xxx]可能.那么为什么不使用你自己的字典而不是污染locals()(并且有可能覆盖你的函数实际需要的变量)?
(只是快速记录其他googlin')
好的,所以修改locals() 不是要走的路(虽然修改globals() 应该有效).在此期间,exec 可能会,但它的速度很慢,因此,正如正则表达式一样,我们可能compile()首先想要它:
# var0 = 0; var1 = 1; var2 = 2
code_text = '\n'.join( "var%d = %d" % (n, n) for n in xrange(3) )
filename = ''
code_chunk = compile( code_text, filename, 'exec' )
# now later we can use exec:
exec code_chunk # executes in the current context
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
62742 次 |
| 最近记录: |