动态设置局部变量

Jon*_*han 97 python dynamic

你如何在Python中动态设置局部变量?

(变量名称是动态的)

更新:我知道这不是一个好的做法,而且这些言论是合法的,但这不是一个坏问题,只是一个更理论的问题 - 我不明白为什么这证明了这一点.

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()(并且有可能覆盖你的函数实际需要的变量)?


ジョー*_*ョージ 5

(只是快速记录其他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 次

最近记录:

5 年,11 月 前