В чем разница между globals()
, locals()
и vars()
? Что они возвращают? Обновлены ли полезные результаты?
Какая разница между глобальными(), 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