2012-12-25 45 views
1

可能重複:
What is the benefit to using a ‘get function’ for a python class?python:爲什麼getter&setter?我如何快速設置屬性?

我剛開始讀Python,但我不知道爲什麼Python的需要setter和getter呢?它已經具有像財產

考慮

class C(object): 
    def _init_(self): 
     self._x = None 

    def get_x(self): 
     return self._x 

    def set_x(self, value): 
     self._x = valu 
    x = property(get_x, set_x) 

我們能不能用C.x =「值」做什麼,我們要在這裏做對象變量?財產有什麼好處?

順便說一句,以這種方式創建屬性/ setter/getter對我來說很麻煩,有什麼方法可以簡化它嗎?像

class C() 
    has_attributes("x", "y", "z") 
+3

你不需要Python中的getter和setter。 –

+0

除了brenbarn發佈什麼,考慮[Python @property與getters和setters](http://stackoverflow.com/questions/6618002/python-property-versus-getters-and-setters) –

+0

還請注意,你可能想要爲了*不*初始化'self._x'到'None',以便在設置之前捕獲嘗試訪問它的代碼的問題。在這種情況下,你可能甚至不需要定義'__init __()'。 – EOL

回答

2
class C(object): 
    def _init_(self): 
     self._x = None 

    def get_x(self): 
     return self._x 

    def set_x(self, value): 
     self._x = value 

    x = property(get_x, set_x) 

現在你可以使用c.x = 「富」 與設定,並得到,透明。

set和getter的目的是不公開類的內部。

試想一下,在未來

self._x 

更改

sql.save(id(self), value) 

和get_x到:

value= sql.sql(id(self)) 
return convertFromDbFormatToExpectedApiFormat(value) 

你只需要改變的getter和setter的代碼只該類,不會更改 所有與之通信的類。

class C(object): 
    def _init_(self): 
     self.sql = DDBB() 

    def get_x(self): 
     dbregistry = self.sql.fetch(id(self)) 
     return convertFromDbFormatToExpectedApiFormat(dbregistry) 

    def set_x(self, value): 
     self.sql.save(id(self), value) 

    x = property(get_x, set_x) 
+0

您的建議適用於Java,但Python調用者不會將將屬性「x」轉換爲使用「get_x」和「set_x」實現的屬性「x」的類。 – PaulMcG

+0

我不完全理解你的論點......可以詳細說明嗎?我認爲當你需要做一些非平凡的邏輯時,使用get和set和property會更清楚,並且只有在預期的微不足道(如果有的話)邏輯時才使用裝飾器@property。對於多語言開發人員來說,明確的setter和getter也更清晰,並且(至少2.7版本)在python文檔中公開詳細闡述。 –

+2

如果您在分配給'x'屬性來調用'set_x'來設置'object._x'的唯一行爲,只需將該屬性定義爲'x',並將其直接指定爲'object.x'。如果事情在未來發生變化(例如像你所描述的那樣添加db持久性),那麼實現setters和getters。調用者不需要改變 - 他們用'sth.x = 100'設置屬性,新代碼將是'sth.x = 100' - 嘿!畢竟沒有改變! (與Java不同的是,這種改變雖然在語法上相同,但需要重新編譯客戶端代碼。) – PaulMcG

2

可以使用property獲得你想要的東西:

c = C() 
c.x = 10 #calls the setter 
print(c.x) #calls the getter 

有一些理由使用:

class C(object): 
    def _init_(self): 
     self._x = None 
    @property 
    def x(self): 
     return self._x 

    @x.setter 
    def x(self, value): 
     self._x = value 

然後你可以用通常的屬性語法訪問屬性屬性而不是明文數據屬性:

  • 您可以記錄屬性
  • 您可以控制訪問屬性,或者通過使其只讀或通過檢查類型/值被設置
  • 你不破壞向後兼容性:如果事情是一個普通的實例屬性,然後您決定將其轉換爲屬性,該屬性的代碼仍然可以工作。如果您使用get/set顯式方法,則使用舊API的所有代碼將不得不更改
  • 使用顯式獲取/設置方法更具可讀性。
3

使用普通的屬性:

class C(object): 
    def __init__(self): 
     self.x = None 

後來時,如果有必要,X是可以改變的一個屬性。 「@property」的美妙之處在於它允許開發人員不使用getters,setters和「@property」。

相關問題