Python vars()全局名称错误
我在理解下面这个函数出问题的地方时遇到了一些麻烦:
def ness():
pie='yum'
vars()[pie]=4
print vars()[pie]
print yum
所以当我运行这个的时候,我得到了这个结果:
>>> ness()
4
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in ness
NameError: global name 'yum' is not defined
如果我不把它写成一个函数,而是直接在命令行里一行一行地输入,它就能正常工作,像这样:
>>> pie='yum'
>>> vars()[pie]=4
>>> print vars()[pie]
4
>>> print yum
4
>>>
编辑:假设我想让事情变得比这更复杂,而不是给yum赋一个值并打印这个值,我定义了一些函数,并想根据一些输入来调用其中一个:
def ness(choo):
dic={}
dessert=()
dnum=[10,100]
desserts='pie'
dic[dessert]=str(desserts[bisect(dnum,choo)])
vars()[dic[dessert]]()
def p():
print 'ummmm ummm'
def i():
print 'hooo aaaaa'
def e():
print 'woooo'
所以当我调用ness时,我得到了一个键错误:
>>> ness(3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 7, in ness
KeyError: 'p'
我知道我可以用一些elif语句来处理这种情况,但我在想这样做是否也可行,使用bisect这样的方式是否会更高效(比如说如果我需要检查1000个choo的值)而不是使用elif。
非常感谢你的帮助。
5 个回答
1
使用 vars() 返回的字典是 不安全 的,最好不要去修改它。
vars([对象])¶
如果没有传入参数,它的作用就像
locals()
。如果传入一个模块、类或者类的实例对象(或者其他有 dict 属性的东西),它会返回那个属性。
注意
返回的字典不应该被修改:对相应的符号表的影响是 不确定 的。
你的第二个例子是一个特殊情况。vars()
在全局命名空间中等同于 globals()
,而 globals()
返回的字典的行为是你可以预期的(但不太推荐这样做)。
>>> id(vars()),id(globals())
(3085426868L, 3085426868L)
2
可以通过exec来实现这个功能。
>>> def ness():
... pie='yum'
... exec pie+"=4"
... print vars()[pie]
... print yum
...
>>>
>>> ness()
4
4
不过,使用一个新的字典会更好,也更安全。
>>> def ness():
... dic={}
... pie='yum'
... dic[pie]=4
... print dic[pie]
... print dic['yum']
...
>>> ness()
4
4
>>>