globals()、 locals()和 vars()之间的区别是什么?他们返回什么?更新结果是否有用?
globals()
locals()
vars()
每一种都会返回一本字典:
locals和 vars可能需要更多的解释。如果在函数内部调用了 locals(),它会使用当前局部变量名称空间(加上任何闭包变量)的值更新一个 dict,并返回它。对同一堆栈帧中的 locals()的多个调用每次都返回相同的 dict- 它作为其 f_locals属性附加到堆栈帧对象。在每个 locals()调用和每个 f_locals属性访问上,dict 的内容都会更新,但在这样的调用或属性访问上,则更新为 只有。当变量被赋值时,它不会自动更新,而且在 dict 中赋值的条目也不会赋值相应的局部变量:
locals
vars
f_locals
import inspect def f(): x = 1 l = locals() print(l) locals() print(l) x = 2 print(x, l['x']) l['x'] = 3 print(x, l['x']) inspect.currentframe().f_locals print(x, l['x']) f()
给我们:
{'x': 1} {'x': 1, 'l': {...}} 2 1 2 3 2 2
第一个 print(l)只显示一个 'x'条目,因为对 l的赋值发生在 locals()调用之后。第二个 print(l)在再次调用 locals()之后显示一个 l条目,尽管我们没有保存返回值。第三个和第四个 print显示赋值变量不更新 l,反之亦然,但是在我们访问 f_locals之后,局部变量又被复制到 locals()中。
print(l)
'x'
l
print
两个注意事项:
exec "pass"
如果 locals()被称为 在外面函数,它将返回当前名称空间的实际字典。对字典中反映的名称空间 是的进一步更改,以及对名称空间中反映的字典 是的更改:
class Test(object): a = 'one' b = 'two' huh = locals() c = 'three' huh['d'] = 'four' print huh
{ 'a': 'one', 'b': 'two', 'c': 'three', 'd': 'four', 'huh': {...}, '__module__': '__main__', }
到目前为止,我所说的关于 locals()的一切对于 vars()也是正确的... ... 这里有一个区别: vars()接受一个对象作为它的参数,如果你给它一个对象,它返回该对象的 __dict__。对于一个典型的对象,它的 __dict__是它的大部分属性数据存储的地方。这包括类变量和模块全局变量:
__dict__
class Test(object): a = 'one' b = 'two' def frobber(self): print self.c t = Test() huh = vars(t) huh['c'] = 'three' t.frobber()
这就给了我们:
three
注意,函数的 __dict__是它的属性名称空间,而不是局部变量。函数的 __dict__存储本地变量是没有意义的,因为递归和多线程意味着可以同时对一个函数进行多次调用,每次调用都有自己的本地变量:
def f(outer): if outer: f(False) print('Outer call locals:', locals()) print('f.__dict__:', f.__dict__) else: print('Inner call locals:', locals()) print('f.__dict__:', f.__dict__) f.x = 3 f(True)
Inner call locals: {'outer': False} f.__dict__: {'x': 3} Outer call locals: {'outer': True} f.__dict__: {'x': 3}
在这里,f递归地调用自己,因此内部调用和外部调用重叠。每个函数在调用 locals()时都会看到自己的本地变量,但是两个调用看到的是相同的 f.__dict__,而且 f.__dict__中没有任何本地变量。
f
f.__dict__