Python的瓦尔()全局名称错误
我有一点很难理解什么是用下面的函数脚麻:Python的瓦尔()全局名称错误
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
>>>
编辑: 假设我想使事情比这更复杂,而不是百胜设定的值并打印该值,我定义了一些功能,并希望基于一些输入调用其中的一个:
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语句,但我不知道这是否会工作太时,如果使用开张像这样会比使用elifs更高效(比如说,如果我需要检查1000个choo值)。
非常感谢您的帮助。
有办法以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
>>>
这是not safe修改()由瓦尔返回的字典
vars([object])¶
Without an argument, act like locals().
With a module, class or class instance object as argument (or anything else that has a dict attribute), return that attribute.
Note
The returned dictionary should not be modified: the effects on the corresponding symbol table are undefined.
你的第二个例子是一个特例。 vars()
相当于globals()
在全局命名空间,并通过globals()
返回的字典表现为你所期望的(但是是不可取的)
>>> id(vars()),id(globals())
(3085426868L, 3085426868L)
vars()
相当于locals()
,该函数在其范围内是局部变量,在交互式解释程序中是vars() is globals()
。 locals()
仅供阅读;试图改变它的效果是不确定的(实际上,它不起作用)。 globals()
可以进行修改,但你仍然应该从未直接放任何东西在它返回的字典。
[编辑:我一定是错的,因为'exec'的例子有效。]
正如大家指出的那样,修改vars()是一个坏主意。但是,通过认识到python在某种意义上不会“看到”“yum”是本地的,你可以理解错误。 “print 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
使用exec做了上面写的更复杂的例子的窍门(没有像我们试图给我们的关键错误电子词典以及变量。究竟使用dict比exec更安全?是什么gnibbler说: “返回的字典不应该被修改:对相应的符号表的影响是不明确的” 这意味着使用exec这种方式可能会导致不可预见的问题? – Jamie 2010-02-09 15:17:12
exec可以执行任何python代码,例如'exec“os.system('reboot_your_pc')”,所以最好避免使用它。 – YOU 2010-02-09 15:49:42
另外exec可以给你一个令人困惑的stacktrace,并且比明确的字典要慢得多(它必须从头开始解析)。 – viraptor 2010-02-28 17:50:13