В чем разница между globals(), 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 - другие Python s могут разрешать обновлениям возвращаться в локальное пространство имен
- В 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