影响

2013-10-12 71 views
-2

是如何在第一个例子中__str__方法返回成功时self.foo尚未定义的字符串:影响

class foo: 
    foo = 'K-Dawg' 

    def __str__(self): 
     return self.foo 

obj = foo() 
print obj 
#K-Dawg 

当我创建一个类的构造方法__init__,这产生:

AttributeError: foo instance has no attribute 'foo'

class foo: 
    def __init__(self): 
     foo = 'K-Dawg' 

    def __str__(self): 
     return self.foo 

obj = foo() 
print obj 

为什么self.foo在第一个示例中成功返回,而不是第二个?

类构造函数对其属性有什么影响?

编辑: 我知道,改变foo = 'K-Dawg'self.foo = 'K-Dawg'将打印K-耶成功,但为什么我问的是,为什么在第一个例子中的属性foo到达使用被称为self.foo

+0

就在旁边注意,'__init__'不是一个构造函数。 – Hyperboreus

回答

6

修改后的第一程序

class foo: 
    foo = 'K-Dawg' 

    def __str__(self): 
     print dir(self) 
     return self.foo 

obj = foo() 
print obj 

修改后的第二计划

class foo: 
    def __init__(self): 
     print locals() 
     foo = 'K-Dawg' 
     print locals() 

    def __str__(self): 
     print locals() 
     return self.foo 

obj = foo() 
print obj 

我只是包括一些打印语句。如果你看看每个程序的输出结果,你将能够弄清楚到底发生了什么。

第一个程序将打印

['__doc__', '__module__', '__str__', 'foo'] 
K-Dawg 

我们可以看到,foo已经存在的对象。实际上,在这种情况下,foo是一个类变量(与类实例无关,如果来自C,C++或JAVA背景,则可以将其视为一个静态变量,它绑定到类而不是Object)。

第二个程序将打印

{'self': <__main__.foo instance at 0x7f528aa90488>} 
{'self': <__main__.foo instance at 0x7f528aa90488>, 'foo': 'K-Dawg'} 
{'self': <__main__.foo instance at 0x7f11f236d488>} 
AttributeError: foo instance has no attribute 'foo' 

这显然告诉我们,变量foo__init__功能得到了创建,但是当它到达__str__它不可。这意味着在__init__中创建的foo变量对于该函数是本地的。

如果你想创建的对象的变量,你应该做这样的事情

class foo: 
    def __init__(self): 
     print locals() 
     self.foo = 'K-Dawg' # Note the self keyword at the beginning 
     print locals() 

    def __str__(self): 
     print locals() 
     return self.foo 

obj = foo() 
print obj 

输出

{'self': <__main__.foo instance at 0x7fe0e2da24d0>} 
{'self': <__main__.foo instance at 0x7fe0e2da24d0>} 
{'self': <__main__.foo instance at 0x7fe0e2da24d0>} 
K-Dawg 

self指向类的当前实例,我们通过做self.foo = 'K-Dawg'附加一个名为foo的变量。这就是为什么这是有效的。

2

在第一个示例中,您创建了一个类属性foo ---在该类的所有实例中共享一个属性。当您尝试访问self.foo时,如果该实例没有自己的foo属性,它将读取该类中的一个。

在第二种情况下,您根本没有创建属性。 foo__init__只是一个局部变量。如果你想创建一个实例变量,你需要:

def __init__(self): 
    self.foo = 'K-Dawg'