globals(),locals()和vars()之间有什么区别?

globals(),locals()和vars()之间有什么区别?,第1张

globals(),locals()和vars()之间有什么区别?

这些每个都返回一个字典

  • globals()
    总是返回模块名称空间的字典
  • locals()
    总是返回当前名称空间的字典
  • vars()返
    回当前名称空间的字典(如果不带参数调用)或参数的字典。

locals
并vars可以使用更多解释。如果
locals()
在函数内部调用,它将使用该时刻的当前局部变量名称空间(加上任何闭包变量)的值来更新字典并返回它。
locals()
每次对同一堆栈框架的多次调用都会返回相同的字典-它作为其
f_locals
属性附加到堆栈框架对象。dict的内容在每次
locals()
调用和每个
f_locals
属性访问时更新,但仅在此类调用或属性访问时更新。分配变量时,它不会自动更新,并且在dict中分配条目不会分配相应的局部变量:

import inspectdef 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 12 32 2

第一个print(l)只显示一个’x’条目,因为分配要l在locals()调用之后进行。再次print(l)调用locals()后,第二个显示一个l条目,即使我们没有保存返回值。第三和第四print步表明分配变量不会更新l,反之亦然,但是在我们访问之后f_locals,局部变量会locals()再次复制到其中。

两个注意事项:

此行为是CPython特有的-其他Python可能允许更新使它自动返回到本地名称空间。
在CPython 2.x中,可以通过exec “pass”在函数中放置一行来使其工作。这会将函数切换到较旧的执行速度较慢的模式,该模式使用locals()dict作为局部变量的规范表示。
如果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__
大多数属性数据都存储在该对象中。这包括类变量和模块全局变量:

class Test(object):    a = 'one'    b = 'two'    def frobber(self):        print self.ct = 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 = 3f(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__没有任何局部变量。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5004056.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-14
下一篇 2022-11-14

发表评论

登录后才能评论

评论列表(0条)

保存