get_zeus_name_1()
пытается получить доступ к глобальной переменной zeus
, которая еще не была инициализирована в момент вызова get_zeus_name_1()
.
get_zeus_name_2()
принимает аргумент (scope
) и получает доступ к тому, что работает. Он не пытается получить доступ к глобальной переменной zeus
.
Та же история с get_name_1()
и get_name_2()
.
Я думаю, что ключевой момент - понять, как python выполняет эту строку:
zeus=Zeus()
Эта строка говорит Python: выполнить метод Zeus()
(который является другим именем для метода __init__(self)
в классе Zeus
), а затем назначить объект, возвращаемый этим методом, глобальной переменной zeus
.
Python сначала выполняет метод Zeus()
, а затем, после , метод init завершил выполнение и возвратил объект-экземпляр класса Zeus, python назначает этот объект глобальной переменной zeus. Таким образом, глобальная переменная zeus не была определена до тех пор, пока не завершится метод init, поэтому get_name_1 () и get_zeus_name_1 () не могут получить к ней доступ.
get_name_2 () и get_zeus_name_2 () обращаются к тому же экземпляру объекта класса Zeus, к которому пытаются получить get_name_1 () и get_zeus_name_1 (), но они получают к нему доступ через параметр, который передается им, а не через глобальную переменную чтобы они не столкнулись с проблемой.
Вот более простой пример, демонстрирующий точно такую же проблему:
>>> class Foo:
... def __init__(self):
... self.name = 'foobar'
... print self.name
... print foo.name
...
>>> foo = Foo()
foobar
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in __init__
NameError: global name 'foo' is not defined
>>>
Строка print self.name
работает просто отлично (эквивалентно get_name_2 () и get_zeus_name_2 ()), но строка print foo.name
падает (эквивалентно get_name_2 () и get_zeus_name_2 ()).