2014-03-28 69 views
7

爲什麼 - 或者爲什麼不 - 在Python OOP中專門使用getter和setter是一個好習慣?爲什麼(或者不是)在Python OOP中使用Getters/Accessors?

我的教科書指出以下:

import random 

class Die(object): 
    """Simulate a generic die.""" 
    def __init__(self): 
     self.sides = 6 
     self.roll() 

    def roll(self): 
     """Updates the die with a random roll.""" 
     self.value = 1+random.randrange(self.sides) 
     return self.value 

    def getValue(self): 
     """Return the last value set by roll().""" 
     return self.value 

def main(): 
    d1,d2 = Die(),Die() 
    for n in range(12): 
     print d1.roll(),d2.roll() 

main() 

的的getValue()的方法,稱爲吸氣劑或訪問,返回值實例變量的值。 爲什麼寫這種功能?爲什麼不簡單地使用實例變量?我們將在本章最後的常見問題中解決這個問題。

但是,本章末尾沒有常見問題解答,因此永遠不會解釋爲什麼getter在Python OOP中使用。

我試過閱讀其他地方,但我還沒有找到一個很好的解釋任何地方。在所以大多數的答案是關於Java和我讀過,這是不相關的Python的 ...

是否有人可以幫助我瞭解爲什麼它是使用它們好的做法呢?如果不是,爲什麼不呢?

+14

它*不是很好的做法,實際上。它在Java中,但不在Python中。 –

+4

我猜測作者對Python並不是很熟悉。事實恰恰相反。 –

+4

請不要關閉。接近的選票提到了一般的面向對象問題。有幾個答案提到了Python,但我認爲這個問題的Python特定版本是有效的。 –

回答

7

因爲在Python有屬性:

class Foo: 
    def __init__(self, value): 
    self.__value = value 

    @property 
    def value(self): 
    return self.__value 

    @value.setter 
    def set_value(self, that): 
    if that < 0: 
     self.__value = 0 
    else: 
     self.__value = that 

屬性使它看起來你正在處理一個屬性,但實際上,你正在處理的getter和setter方法。這可以更好地利用Python的一個定義特徵:鴨子打字。

因此,我可以做到以下幾點:

class Bar: 
    def __init__(self, value, other): 
    self.value = value 
    self.other = other 

    def __str__(self): 
    return ''.join(['Oh joy', str(self.value), str(self.other), '!']) 

然後在功能:

def stuff(x): 
    return x.value + 1 

我可以通過其中一種類型的Bar或類型的Foo,它不會物。鴨子打字會讓它「只是工作」。

+0

-1有關鴨子打字的一點,我相信這完全不相關。此外,您可能希望將「處理變量」更改爲「處理屬性」。 –

+2

@StevenRumbalski實際上,我認爲Duck Typing與Python的核心高度相關和重要。但我同意,「屬性」是一個更好的術語。 – wheaties

+1

當然,Python是關於鴨子打字的,但這不是屬性的全部內容。它們是關於將函數調用僞裝成屬性訪問。好的是,它們看起來完全像屬性訪問,所以你開始無財產,然後在必要時添加它們。 –

3

在Java中,你應該使用getter和setter方法:

它認爲是一個很好的做法,因爲它封裝了你的對象的內部狀態,因此,你可以改變物體的內部結構和改變數值的含義,做複雜的事情與它沒有改變它的界面。

在Python 可以使用getter和setter方法:

但它沒有那麼多強調對訪問某個屬性的值,因爲Python提供了一個設施,Java則沒有:屬性!

class A(object): 
    def __init__(self): 
     self._x = 1 
    @property 
    def x(self): 
     return self._x +2 
    @x.setter 
    def x(self, value): 
     self._x = value 

這是您的內置語法,用於在不更改接口的情況下更改屬性的含義。使用它就像使用你的平均屬性語法。

+2

在Java中需要它們的真正原因是,當你需要添加一些額外的行爲時,重構所有使用屬性訪問的東西是一種痛苦。這種「封裝」巨型巨人只是爲了掩蓋糟糕的語言設計決策。 –

+1

@gnibbler正是!但我不會這麼說,因爲我知道他們在外面,Java愛好者,他們是軍團,他們正在尋找血液。但我不會執行我的血液訪問器! AH-HA! – ddelemeny

相關問題