2013-02-28 42 views
0

這些都工作:在對象中訪問類變量的最佳方法?

class A: 
    V = 3 
    def getV(self): 
     return self.V 
    def getVbis(self): 
     return A.V 

print A().getV() 
print A().getVbis() 

哪一個更Python?爲什麼?

+0

'getVbis()'沒有錯?兩者都是不相同的代碼 – 2013-02-28 16:38:40

+1

他們做不同的事情。您已將V定義爲* class * A的變量,而不是A的實例變量。它在所有類之間共享。然而,試圖獲得'self.V'將會,如果self沒有屬性V,則查找屬於自己類的屬性V,這就是它們都工作的原因。如果你多次實例化這個;在你的所有實例中,你的setter都將引用在類的所有實例之間共享的同一個對象 - 儘管這可能不會讓你在這裏,因爲int是不可變的,並且賦值給self.V將創建一個實例屬性。 – 2013-02-28 16:40:51

+0

如果你在概念上希望V是實例的屬性而不是類,你應該在你的類的'__init__'方法中爲'self_V = 3',而不是類定義中的V = 3。 – 2013-02-28 16:42:53

回答

3

self.V包含一個實例變量的值,而A.V包含一個類變量的值。根據你的班級方法對V的做法以及他們如何做,getVgetVbis將返回不同的內容。

下面是一個例子:

class A: 
    V = 3 
    def getV(self): 
     return self.V 
    def getVbis(self): 
     return A.V 
    def setV(self, newVal): 
     self.V = newVal 

aInst = A() 
print aInst.getV() 
print aInst.getVbis() 
aInst.setV(5) 
print aInst.getV() 
print aInst.getVbis() 

上面的代碼將導致以下:

3 
3 
5 
3 

所以我不認爲這是關於哪一個更Python。相反,這是關於你想要用你的類變量做什麼。

2

儘管代碼的實際意義,我認爲getter/setter方式不是pythonic。

首先變量默認是公共的。 getter func使它更復雜;

其次,如果你想在getter/setter func中有一些約束或其他邏輯,它應該有一個更明顯的名稱來表示邏輯。名字getXXX意味着什麼。

順便說一句,如果你真的不想直接訪問變量,還有另一種選擇:http://docs.python.org/2/library/functions.html#property

+0

這只是一個例子。在我的真實代碼中,我沒有實現getter/setter。我只是在對象中使用類變量(對我來說這是一個常量:我沒有改變它),我不確定self.V是否優於A.V. – dangonfast 2013-02-28 21:17:02

0

我自己也更喜歡訪問類成員(屬性和方法)的實例方法中的實例方法。我不知道它是否更加Pythonic,但它允許我專注於接口,因爲我總是可以用實例成員覆蓋類成員。這種情況下的類成員提供了一些有用的默認值(值或實現)。

0

它可能不是很漂亮,但我更喜歡:

self.__class__.V 

這樣你就不必明確提及類名,這使得更容易繼承,並沒有意外得到一個危險實例屬性而不是類屬性。

相關問題