fra*_*xel 2 python oop instantiation init
好吧,我也是SO,OOP和python的新手,所以请温柔;)
我在其他地方寻找与此范围问题相关的线索和解释,但没有发现任何问题.如有任何帮助,我将不胜感激.
示例代码:
class Zeus(object):
def __init__(self):
self.name='zeus'
self.maze=Maze()
self.maze.get_zeus_name_1()
self.maze.get_zeus_name_2(self)
self.get_name_1()
self.get_name_2(self)
def get_name_1(self):
try:
print zeus.name
except:
print "impossible!?"
def get_name_2(self,scope):
print scope.name
class Maze(object):
def get_zeus_name_1(self):
try:
print zeus.name
except:
print "can't be done!?"
def get_zeus_name_2(self,scope):
print scope.name
zeus=Zeus()
print 'now external calls:'
zeus.maze.get_zeus_name_1()
zeus.maze.get_zeus_name_2(zeus)
zeus.get_name_1()
zeus.get_name_2(zeus)
Run Code Online (Sandbox Code Playgroud)
输出:
can't be done!?
zeus
impossible!?
zeus
now external calls:
zeus
zeus
zeus
zeus
Run Code Online (Sandbox Code Playgroud)
在实例化期间zeus,如果__init__方法创建另一个类的实例maze,则此新实例无法访问其创建者对象zeus(除非self传递给它).(另外,如果__init__方法在其自己的类中调用方法get_name_1,则该方法也无法访问其对象属性(除非self传递给它).)
但是,在对象被实例化之后,第二个对象maze现在可以识别并访问其创建者对象,zeus.
这种行为给我带来了一些困惑和困难,因为我正在编写一些代码,其中所有内容__init__都已初始化并从序列中运行- 现在我认为最好避免这种情况.
我的问题:
__init__?self给一个新实例,似乎可能会因为自我引用而产生问题,是否也应该避免这种情况?谢谢你的帮助.
get_zeus_name_1()正在尝试访问全局变量zeus,该变量在get_zeus_name_1()被调用时尚未初始化.
get_zeus_name_2()接受一个参数(scope)并访问它,这是有效的.它不会尝试访问全局变量zeus.
与get_name_1()和相同的故事get_name_2().
我认为关键是要了解python如何执行这一行:
zeus=Zeus()
Run Code Online (Sandbox Code Playgroud)
这行告诉python:执行方法Zeus()(这是类中__init__(self)方法的另一个名称Zeus),然后将该方法返回的对象分配给全局变量zeus.
Python首先执行该方法Zeus(),然后,在 init方法完成执行并返回Zeus类的对象实例后,python将该对象分配给全局变量zeus.因此,在init方法完成之前,尚未定义全局变量zeus,因此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
>>>
Run Code Online (Sandbox Code Playgroud)
该print self.name行正常工作(相当于get_name_2()和get_zeus_name_2()),但该print foo.name行崩溃(相当于get_name_2()和get_zeus_name_2()).