Python vars()全局名称错误

3 投票
5 回答
3220 浏览
提问于 2025-04-15 19:03

我在理解下面这个函数出问题的地方时遇到了一些麻烦:

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 个回答

4

在一个函数里面使用 vars() 会给你这个函数的局部变量,就像 locals() 一样。你可以在文档中查看详细信息。在函数外面(比如在命令行中),locals()(当然还有 vars())会给你模块的全局变量,就像 globals() 一样。正如文档所说,通过 locals()(或者在函数里面的 vars())去给函数的局部变量赋值在 Python 中是不被支持的。如果你想给一个全局变量赋值,就像在命令行中那样(或者在函数外面),你应该使用 globals() 而不是 vars()(虽然这可能不是最好的方法——全局变量通常不太受欢迎——但确实可以用)。

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
>>>

撰写回答