Python中的vars()提供不同的输出

Python中的vars()提供不同的输出,python,string,names,variables,Python,String,Names,Variables,当我运行此代码时: a = '1' vars()['a'] = '2' print a def bar(): a = '1' vars()['a'] = '2' print a bar() 我得到以下输出: 2 1 但当我运行此代码时: a = '1' vars()['a'] = '2' print a def bar(): a = '1' vars()['a'] = '2' print a bar() 我得到以下输出: 2 1

当我运行此代码时:

a = '1'
vars()['a'] = '2'
print a
def bar():
    a = '1'
    vars()['a'] = '2'
    print a

bar()
我得到以下输出:

2
1
但当我运行此代码时:

a = '1'
vars()['a'] = '2'
print a
def bar():
    a = '1'
    vars()['a'] = '2'
    print a

bar()
我得到以下输出:

2
1
现在我的问题是为什么会发生这种情况,我如何才能让第二个案例给出与第一个案例相同的解决方案

编辑:

真的找不到解决方案,但我发现了一个小漏洞。。。虽然我不想使用exec:

def bar():
    a = "a"
    b = "b"
    exec a+"="+b
    print a

bar()
这让我得到了结果:

b

如果有人能找到更好的解决方案,那就太好了。我没有这样设置任何全局变量,也没有做任何疯狂的事情,所以不用担心。

新样式的类似乎覆盖了默认的
\uuuu dict\uuu
行为,从而打破了
vars()的这种用法。不确定它为什么会影响旧式类,但它可能是相关的

来自文档(http://docs.python.org/library/functions.html#vars):


vars([object])
返回模块、类、实例或任何其他具有
\uuuuuuuu dict\uuu
属性的对象的
\uuuuu dict\uuuuu
属性

模块和实例等对象具有可更新的
\uu dict\uu
属性;但是,其他对象可能对其
\uuuu dict\uuu
属性有写限制(例如,新样式的类使用dictproxy来防止直接更新字典)

在没有参数的情况下,vars()的行为类似于locals()。请注意,局部变量字典仅对读取有用,因为对局部变量字典的更新将被忽略



你能谈谈为什么
self.=val
setattr(self'x',val)
不适用于您的课堂案例?

未定义对
vars()结果的赋值。因此,它可能会在不同的场景和/或python版本和/或实现中给出不同的结果。虽然用这种方式更改局部变量听起来可能令人震惊(我曾经尝试过用它来处理regex-groupdict结果),但这是非常不可移植的,并且可能随时中断。

文档的这一部分似乎是关键:“注意,局部字典只对读取有用,因为忽略了对局部字典的更新。”。,您不应该修改vars()返回的任何内容。我认为这与类无关,因为我可以删除类部分,但仍然存在相同的问题。我认为问题在于功能。我已经试过了val和setattr(self,'x',val),但仍然得到了相同的结果。我相信这个类没有什么区别——这是局部范围和全局范围的问题。此外,如果你试图在函数中以这种方式设置全局变量,你可能犯了可怕的错误。