globals()、locals() 和 vars() 之间有什么区别? [英] What's the difference between globals(), locals(), and vars()?

查看:66
本文介绍了globals()、locals() 和 vars() 之间有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

globals()locals()vars() 之间有什么区别?他们返回什么?更新结果有用吗?

What is the difference between globals(), locals(), and vars()? What do they return? Are updates to the results useful?

推荐答案

每个都返回一个字典:

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

localsvars 可以使用更多的解释.如果 locals() 在函数内被调用,它会用当前局部变量命名空间(加上任何闭包变量)的值更新一个 dict 并返回它.在同一堆栈帧中多次调用 locals() 每次都返回相同的 dict - 它作为其 f_locals 属性附加到堆栈帧对象.dict 的内容在每次 locals() 调用和每个 f_locals 属性访问时更新,但在此类调用或属性访问时更新.变量赋值时不会自动更新,在dict中赋值不会赋值对应的局部变量:

locals and vars could use some more explanation. 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. 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. The dict's contents are updated on each locals() call and each f_locals attribute access, but only on such calls or attribute accesses. It does not automatically update when variables are assigned, and assigning entries in the dict will not assign the corresponding local variables:

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

The first print(l) only shows an 'x' entry, because the assignment to l happens after the locals() call. The second print(l), after calling locals() again, shows an l entry, even though we didn't save the return value. The third and fourth prints show that assigning variables doesn't update l and vice versa, but after we access f_locals, local variables are copied into locals() again.

两个注意事项:

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

如果 locals() 被调用外部一个函数,它返回当前命名空间的实际字典.对命名空间的进一步更改反映在字典中,而对字典的更改反映在命名空间中:

If locals() is called outside a function it returns the actual dictionary that is the current namespace. 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

给我们:

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

到目前为止,我所说的关于 locals() 的所有内容也适用于 vars()...区别在于:vars() 接受单个对象作为其参数,如果给它一个对象,它会返回该对象的 __dict__.对于典型的对象,它的 __dict__ 是其大部分属性数据的存储位置.这包括类变量和模块全局变量:

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. For a typical object, its __dict__ is where most of its attribute data is stored. 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()

这给了我们:

three

请注意,函数的 __dict__ 是它的属性命名空间,而不是局部变量.函数的 __dict__ 存储局部变量是没有意义的,因为递归和多线程意味着可以同时对函数进行多次调用,每个调用都有自己的局部变量:

Note that a function's __dict__ is its attribute namespace, not local variables. 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:

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__ 没有'里面没有任何局部变量.

Here, f calls itself recursively, so the inner and outer calls overlap. 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.

这篇关于globals()、locals() 和 vars() 之间有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆