2013-05-14 51 views
2

在使用Django一段時間後,我在聲明變量時習慣了使用沒有def __init__(self): ...的類。我曾經在__init__函數中聲明我的變量,現在我意識到有些情況下不需要,我只是不清楚何時使用它。在嘗試將類傳遞給變量時看起來有問題,在這些情況下,我應該使用init嗎?創建類時何時使用__init__

我知道我可以在所有情況下只使用__init__,但它只是讓我的短課程更像沒有它的清潔工,所以我想知道我什麼時候可以使用而不能使用它。

例如:在類中聲明

class BaseScraper(object): 
    # whithout __init__, passing Site() to site wont work. 
    # site = Site() 
    # parser = None 

    def __init__(self): 
     self.site = Site() 
     self.parser = None 


class Site(object): 
    # no trouble declaring url as a str 
    url = "" 

    def set(self, url): 
     self.url = url 

    def get(self): 
     return self.url 



if __name__ == "__main__": 
    scraper = BaseScraper() 

    scraper.site.set('http://www.google.com') 
    print scraper.site.get() 
+1

Django不真正代表了Python。 Django模型字段是類級別的屬性,它們實際上是實際的對象,它們根本不是數據的「持有者」,它們用作基礎'Model'的__init __()'方法(或某些代碼的其他部分)用於自動創建實例級屬性並執行其他一些操作。 Python通常不會以這種方式工作。 – millimoose

+1

初始化實例數據時,除非知道自己在做什麼,否則應該在'__init__'中執行。 (類級別的屬性有點類似於它們的默認值,對於實例屬性來說有點不妥當,但有一些注意事項。) – millimoose

+0

這很有趣,謝謝解釋 – Crispy

回答

5

屬性是由類,而不是通過類的各個實例擁有。在您的site示例中,url不再是個別Site對象的屬性,而是setget。對於這種示例,您需要實例數據 - 您可以在__init__中進行初始化。

Python: Difference between class and instance attributes有很好的討論區別。

+1

好吧,這是一個完美的解釋,謝謝 – Crispy

0

這會失敗,因爲Site類尚未定義。 (和@Peter DeGlopper)說,類變量和實例變量之間有很大的區別。

class BaseScraper(object): 
    # This fails! 
    site = Site() 
    parser = None 


class Site(object): 
    # no trouble declaring url as a str 
    url = "" 

    def set(self, url): 
     self.url = url 

    def get(self): 
     return self.url 

當虛擬機編譯一個python模塊,讀取和編譯的類聲明一切,但對方法聲明(如def __init__(...):)只讀這一行,忽略方法主體。

例子:

class Foo(object): 
    bar1 = "bar" 
    foo1 = "foo" 

    def __init__(self): 
     self.bar2 = "BAZ" 

foo = Foo #Put a class in a veriable? yes, you can. 
foo.bar1 # returns "bar" 
foo.foo1 # returns "foo" 
foo.bar2 # fails!!!! This will be a instance variable, but doesn't exist yet 

foo2 = Foo() # Here the __init__ is called 
foo2.bar2 # returns "BAZ" 
foo2.bar1 #Returns "bar" because all class variables are availables from instances 

希望這有助於=)