Какая разница между глобальными(), locals() и vars()?

В чем разница между globals(), locals() и vars()? Что они возвращают? Обновлены ли полезные результаты?

Ответ 1

Каждый из них возвращает словарь:

  • globals() всегда возвращает словарь пространства имен модулей
  • locals() всегда возвращает словарь текущего пространства имен
  • vars() возвращает либо словарь текущего пространства имен (если он вызван без аргумента), либо словарь аргумента.

locals и vars могли бы использовать еще несколько объяснений. если locals() вызывается внутри функции, он строит словарь пространства имен функций с этого момента и возвращает его - любые дальнейшие присвоения имен не отражаются в возвращаемом словаре, а любые присвоения словаря не отражаются в фактическом локальное пространство имен:

def test():
    a = 1
    b = 2
    huh = locals()
    c = 3
    print(huh)
    huh['d'] = 4
    print(d)

дает нам:

{'a': 1, 'b': 2}
Traceback (most recent call last):
  File "test.py", line 30, in <module>
    test()
  File "test.py", line 26, in test
    print(d)
NameError: global name 'd' is not defined

Две заметки:

  • Это поведение специфично для CPython - другие Pythons могут позволить обновлениям возвращать его в локальное пространство имен
  • В CPython 2.x эту работу можно выполнить, поместив в функцию строку 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__ это пространство имен объектов:

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__, но если вы не делаете веселый и интересный материал, его, вероятно, не очень полезно:

def test():
    a = 1
    b = 2
    print test.c
huh = vars(test)       # these two lines are the same as 'test.c = 3'
huh['c'] = 3
test()

который дает нам:

3