影響

2013-10-12 72 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'