2014-12-02 58 views
0

以下兩段代碼是否有區別?如果沒有,是否比另一個更受歡迎?爲什麼我們會被允許動態創建類屬性?Python中的類屬性

片段1

class Test(object): 
    def setClassAttribute(self): 
     Test.classAttribute = "Class Attribute" 

Test().setClassAttribute() 

片段2

class Test(object): 
    classAttribute = "Class Attribute" 

Test() 
+1

我會用第二個。這取決於你是否想要控制創作。如果沒有,我會避免代碼行和額外的函數調用。另外'setClassAttribute'應該是一個classmethod,否則它是沒有意義的。 – wenzul 2014-12-02 19:31:13

+0

我同意wenzul。他們是相同的,但是#1,如果你忘記了,你會有一些有趣的錯誤。 – matsjoyce 2014-12-02 19:33:48

+0

創建類實例以設置類的屬性是沒有意義的,所以都不是首選。另外,你對這件事的看法是什麼? – 2014-12-02 19:36:19

回答

1

做起來更自然它就像#2,但注意他們做了不同的事情。 #2,班級總是有屬性。使用#1,只有在致電setClassAttribute之後才能擁有該屬性。

你問:「爲什麼我們被允許動態創建類屬性?」對於Python,問題通常不是「爲什麼我們會被允許」,而是「爲什麼我們應該被阻止?」一個類與其他任何對象一樣,它具有屬性。對象(通常)可以隨時獲得新的屬性。沒有理由讓班級成爲該規則的例外。

0

我覺得#2感覺更自然。 #1的實現意味着該屬性不會被設置,直到類的實際實例被創建,這對我而言似乎與類屬性(對象屬性)應該是什麼違反直覺。

5

首先,在實例方法上設置類屬性是一件很奇怪的事情。而忽略了self參數,並在同行Test是做另一個奇怪的事情,除非你特別希望所有子類共享一個值。*

*如果您沒有特別希望所有子類共享一個值,我把它設爲@staticmethod沒有參數(並將其設置爲Test)。但在這種情況下,它甚至沒有真正用作類屬性,並且可能作爲全局模塊更好地工作,並且具有自由函數來設置它。

所以,即使你想一起去的第一個版本,我會寫這樣的:

class Test(object): 
    @classmethod 
    def setClassAttribute(cls): 
     cls.classAttribute = "Class Attribute" 

Test.setClassAttribute() 

然而,所有他這樣說,我覺得第二個是更Python的。以下是考慮因素:

  • 一般來說,Python中強烈建議getter和setter。
  • 第一個留下類存在的空白,但沒有屬性。
  • 簡單勝過複雜。

有一兩件事要記住的是原因getter和setter是不必要在Python那部分,你可以隨時更換用@property的屬性,如果你以後需要它來計算,驗證等等。對於類屬性來說,這並不是完美的解決方案 - 但它通常足夠好。


最後一兩件事:類屬性(和類方法,除了可選的構造)常常在較高水平的非Python化設計的標誌。當然,不是總是,但往往不夠,因此值得大聲解釋爲什麼你認爲你需要一個類屬性並確保它是有意義的。 (如果你曾經用一種語言來編程,這種語言的成語廣泛使用了類屬性 - 尤其是如果它是Java的話 - 去找一個從未使用過Java的人並試着向他解釋它。)