简体   繁体   English

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

[英]What's the difference between globals(), locals(), and vars()?

What is the difference between globals() , locals() , and vars() ? globals()locals()vars()之间有什么区别? What do they return?他们返回什么? Are updates to the results useful?结果的更新有用吗?

Each of these return a dictionary:每个都返回一个字典:

  • globals() always returns the dictionary of the module namespace globals()总是返回模块命名空间的字典
  • locals() always returns a dictionary of the current namespace locals()总是返回当前命名空间字典
  • vars() returns either a dictionary of the current namespace (if called with no argument) or the dictionary of the argument. vars()返回当前命名空间字典(如果没有参数调用)或参数字典。

locals and vars could use some more explanation. localsvars可以使用更多的解释。 If locals() is called inside a function, it updates a dict with the values of the current local variable namespace (plus any closure variables) as of that moment and returns it.如果locals()在函数内部被调用,它会用当前局部变量命名空间(加上任何闭包变量)的值更新一个 dict 并返回它。 Multiple calls to locals() in the same stack frame return the same dict each time - it's attached to the stack frame object as its f_locals attribute.在同一堆栈帧中多次调用locals()每次都返回相同的 dict - 它作为其f_locals属性附加到堆栈帧对象。 The dict's contents are updated on each locals() call and each f_locals attribute access, but only on such calls or attribute accesses. dict 的内容在每次locals()调用和每次f_locals属性访问时更新,但仅限于此类调用或属性访问。 It does not automatically update when variables are assigned, and assigning entries in the dict will not assign the corresponding local variables:分配变量时不会自动更新,并且在dict中分配条目不会分配相应的局部变量:

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

gives us:给我们:

{'x': 1}
{'x': 1, 'l': {...}}
2 1
2 3
2 2

The first print(l) only shows an 'x' entry, because the assignment to l happens after the locals() call.第一个print(l)只显示一个'x'条目,因为对l的赋值发生在locals()调用之后。 The second print(l) , after calling locals() again, shows an l entry, even though we didn't save the return value.第二个print(l) ,在再次调用locals()之后,显示了一个l条目,即使我们没有保存返回值。 The third and fourth print s show that assigning variables doesn't update l and vice versa, but after we access f_locals , local variables are copied into locals() again.第三个和第四个print s 显示分配变量不会更新l ,反之亦然,但是在我们访问f_locals ,局部变量再次被复制到locals()

Two notes:两个注意事项:

  1. This behavior is CPython specific -- other Pythons may allow the updates to make it back to the local namespace automatically.此行为是特定于 CPython 的——其他 Python 可能允许更新使其自动返回到本地命名空间。
  2. In CPython 2.x it is possible to make this work by putting an exec "pass" line in the function.在 CPython 2.x 中,可以exec "pass"在函数中放置一个exec "pass"行来完成这项工作。 This switches the function to an older, slower execution mode that uses the locals() dict as the canonical representation of local variables.这将函数切换到使用locals() dict 作为局部变量的规范表示的旧的、较慢的执行模式。

If locals() is called outside a function it returns the actual dictionary that is the current namespace.如果locals()函数外部调用,它返回当前命名空间的实际字典。 Further changes to the namespace are reflected in the dictionary, and changes to the dictionary are reflected in the namespace:命名空间进一步变化反映在字典中,并到词典中的变化反映在名称空间:

class Test(object):
    a = 'one'
    b = 'two'
    huh = locals()
    c = 'three'
    huh['d'] = 'four'
    print huh

gives us:给我们:

{
  'a': 'one',
  'b': 'two',
  'c': 'three',
  'd': 'four',
  'huh': {...},
  '__module__': '__main__',
}

So far, everything I've said about locals() is also true for vars() ... here's the difference: vars() accepts a single object as its argument, and if you give it an object it returns the __dict__ of that object.到目前为止,我所说的关于locals()所有内容对于vars()也是正确的……区别在于: vars()接受单个对象作为其参数,如果给它一个对象,它会返回该对象的__dict__目的。 For a typical object, its __dict__ is where most of its attribute data is stored.对于典型的对象,其__dict__是其大部分属性数据的存储位置。 This includes class variables and module globals:这包括类变量和模块全局变量:

class Test(object):
    a = 'one'
    b = 'two'
    def frobber(self):
        print self.c
t = Test()
huh = vars(t)
huh['c'] = 'three'
t.frobber()

which gives us:这给了我们:

three

Note that a function's __dict__ is its attribute namespace, not local variables.请注意,函数的__dict__是它的属性命名空间,而不是局部变量。 It wouldn't make sense for a function's __dict__ to store local variables, since recursion and multithreading mean there can be multiple calls to a function at the same time, each with their own locals:函数的__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)

which gives us:这给了我们:

Inner call locals: {'outer': False}
f.__dict__: {'x': 3}
Outer call locals: {'outer': True}
f.__dict__: {'x': 3}

Here, f calls itself recursively, so the inner and outer calls overlap.在这里, f递归调用自身,因此内部和外部调用重叠。 Each one sees its own local variables when it calls locals() , but both calls see the same f.__dict__ , and f.__dict__ doesn't have any local variables in it.每个调用locals()时都会看到自己的局部变量,但是两个调用看到的都是相同的f.__dict__ ,而f.__dict__中没有任何局部变量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM