Python vars()全局名称错误

时间:2010-02-09 02:38:47

标签: python global

我在理解以下功能出现问题时遇到了一些麻烦:

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(3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 7, in ness
KeyError: 'p'

现在我知道我可以用一些elif语句做这样的事情,但是我想知道这是否也会起作用,如果使用这样的bisect会更有效(比如我需要检查1000个值的值)而不是使用elifs。

非常感谢您的帮助。

5 个答案:

答案 0 :(得分:4)

函数中的

vars()为您提供了本地命名空间,就像locals()一样 - 请参阅the docs。在函数之外(例如在提示符处)locals()(当然还有vars())为您提供模块的全局命名空间,就像globals()一样。正如the docs所说,Python中不支持尝试通过locals()(或等效地,函数内的vars())分配给函数的局部变量。如果要分配给全局变量,就像在提示时(或在函数外部)一样,请使用globals()而不是vars()(也许不是最干净的方法 - 全球变量可以理解为不赞成 - 但确实有效。)

答案 1 :(得分: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
>>>

答案 2 :(得分:1)

修改vars()

返回的字典是not safe
  

瓦尔([对象])¶

     

没有参数,就像locals()一样。

     

使用模块,类或类实例对象作为参数(或   其他任何有字典的东西   属性),返回该属性。

     

请注意

     

不应修改返回的字典:对...的影响   相应的符号表是   未定义。

你的第二个例子是一个特例。 vars()相当于全局命名空间中的globals(),而globals()返回的dict的行为正如您所期望的那样(但不赞成)

>>> id(vars()),id(globals())
(3085426868L, 3085426868L)

答案 3 :(得分:0)

vars()等同于locals(),在函数的情况下,它是其范围内的局部变量,并且在您拥有它的范围内的交互式解释器中vars() is globals()locals()仅供阅读;尝试改变它的效果是未定义的(实际上,只是不起作用)。 globals() 可以进行修改,但仍然不应该直接在它返回的dict中放入任何内容。

答案 4 :(得分:0)

[编辑:我在这里肯定是错的,因为'exec'示例有效。]

正如大家所指出的,修改变量()是一个坏主意。但是,您可以通过认识到python在某种意义上并不“看到”“yum”是本地的来理解错误。 “印刷百胜”仍然作为全球参考而得到解决;这在任何代码执行之前就会发生。

这与您从以下地址获得UnboundLocalError的原因相同:

>>> y = 100
>>> def foo(x):
...   if x == 1:
...     y = 10
...   print y
... 
>>> foo(1)
10
>>> foo(2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in foo
UnboundLocalError: local variable 'y' referenced before assignment