Dynamically set local variable
如何在python中动态设置局部变量?
(变量名是动态的)
最新消息:我知道这不是一个好的做法,而且这些言论是合法的,但这并不意味着这是一个坏问题,只是一个更理论化的问题——我不明白为什么这会证明投反对票是正当的。
与其他已发布的答案相反,您不能直接修改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | >>> 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 |
修改
使用字典或在对象上设置属性:
1 2 3 | d = {} d['xyz'] = 42 print(d['xyz']) |
或者,如果您愿意,使用一个类:
1 2 3 4 5 | class C: pass obj = C() setattr(obj, 'xyz', 42) print(obj.xyz) |
编辑:对名称空间中不属于函数的变量(因此模块、类定义、实例)的访问通常是通过字典查找来完成的(正如sven在注释中指出的那样,也有例外,例如定义
在python
在Ironpython中,工作方式有点不同。在函数内部调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | >>> 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} >>> |
这一切随时都可能改变。唯一可以保证的是,您不能依赖于分配给
其他人建议分配给
1 2 3 4 5 6 7 | def func(varname): locals()[varname] = 42 return answer # only works if we passed in"answer" for varname exec"" # never executed func("answer") >>> 42 |
注意:这只在python 2.x中有效。他们在python 3中消除了这种愚蠢,其他实现(jython、ironpython等)也可能不支持它。
不过,这是个坏主意。如果不知道变量的名称,您将如何访问这些变量?可能是
(只是给其他人的一个简短说明)
好的,所以修改
1 2 3 4 5 6 7 8 9 | # var0 = 0; var1 = 1; var2 = 2 code_text = ' '.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 |
我已经花了最后的时间…我猜,几个小时后,我试图绕过缺少函数闭包的问题,我想到了这一点,这可能有助于:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | common_data = ...stuff... def process(record): ...logic... def op(): for fing in op.func_dict: # Key line number 1 exec(fing +" = op.func_dict[fing]") # Key line number 2 while common_data.still_recieving: with common_data._lock: if common_data.record_available: process(common_data.oldest_record) time.sleep(1.0) op.func_dict.update(locals()) # Key line number 3 threading.Thread(target = op).start() ... |
这是一个非常沉重的/人为的例子,但是如果有很多本地人,或者您仍在进行原型化的过程中,那么这个模式就变得有用了。大多数情况下,我只是对为处理回调委托而复制或移动的所有数据存储感到苦恼。
您可以直接修改
1 | locals()['foo'] = 'bar' |
但更好的方法是让一些dict将所有动态变量名保存为字典键:
1 2 3 | d = {} for some in thing: d[some] = 'whatever' |
假设我们有以下字典:
1 2 3 4 5 6 | DictionaryA = {'No Rating': ['Hobbit', 'Movie C', 'Movie G'], 'Forget It': ['Avenger', 'Movie B'], 'Must See': ['Children of Men', 'Skyfall', 'Movie F'], '3': ['X-Men', 'Movie D'], '2': ['Captain America', 'Movie E'], '4': ['Transformers', 'Movie A']} |
我想创建如下的新词典:
1 2 3 | NewDictionary1 = {'No Rating': ['Hobbit', 'Movie C', 'Movie G']} NewDictionary2 = {'Forget It': ['Avenger', 'Movie B']} NewDictionary3 = {'Must See': ['Children of Men', 'Skyfall', 'Movie F']} |
Onelier-:
1 | dics = [{k:v} for k,v in DictionaryA.iteritems()] |
将输出到:
1 | [{'Must See': ['Children of Men', 'Skyfall', 'Movie F']}, {'Forget It': ['Avenger', 'Movie B']}, {'No Rating': ['Hobbit', 'Movie C', 'Movie G']}, {'3': ['X-Men', 'Movie D']}, {'2': ['Captain America', 'Movie E']}, {'4': ['Transformers', 'Movie A']}] |
但是为了精确地声明变量,我们可以使用:
1 2 3 4 5 | >>> i=0 >>> lcl = locals() >>> for key,val in DictionaryA.iteritems(): lcl["Dict" + str(i)] = {key:val} i += 1 |
如前3个
1 2 3 4 5 6 | >>> Dict0 {'Must See': ['Children of Men', 'Skyfall', 'Movie F']} >>> Dict1 {'Forget It': ['Avenger', 'Movie B']} >>> Dict2 {'No Rating': ['Hobbit', 'Movie C', 'Movie G']} |
如其他人所述,如果要将其放入函数中,应将其添加到EDOCX1[1]中:
1 2 3 4 | >>> glb = globals() >>> for key,val in DictionaryA.iteritems(): glb["Dict" + str(i)] = {key:val} i += 1 |
您可以使用本地字典并将所有动态绑定作为项放入字典。然后,知道这样一个"动态变量"的名称,就可以使用该名称作为获取其值的键。