2010-11-15 100 views
52

我試圖用新的樣式屬性聲明:「無法設置屬性」與新樣式屬性在Python

class C(object): 
    def __init__(self): 
     self._x = 0 

    @property 
    def x(self): 
     print 'getting' 
     return self._x 

    @x.setter 
    def set_x(self, value): 
     print 'setting' 
     self._x = value 

if __name__ == '__main__': 
    c = C() 
    print c.x 
    c.x = 10 
    print c.x 

並查看控制檯以下:

pydev debugger: starting 
getting 
0 
File "\test.py", line 55, in <module> 
c.x = 10 
AttributeError: can't set attribute 

我究竟做錯了什麼? P.S .:舊式宣言正常。

+0

我已經回滾了將'setting'(一個文檔字符串)變成'print'setting'(一個簡單的調試語句)的編輯。雖然打印語句的意圖確實是合理的,但文檔字符串中沒有任何傷害或錯誤,它根本不會影響問題。 – 2016-01-18 22:10:40

回答

76

The documentation says the following有關使用的property裝飾形式:(X在這種情況下)

一定要給予額外的功能相同的名稱與原始屬性

我有不知道爲什麼這是因爲如果你使用property作爲函數返回一個屬性的方法可以調用任何你喜歡的。

所以,你需要更改您的代碼如下:

@x.setter 
def x(self, value): 
    'setting' 
    self._x = value 
+0

啊,太棒了,我在另一個地方看到了這個,但是認爲他們可能對python缺乏方法重載不知道。這實際上看起來比'set_x'的名稱更清潔! :) – Darthfett 2012-02-23 16:22:50

+0

什麼是「設置」字符串? – zakdances 2013-03-04 22:47:03

+1

@yourfriendzak - 這是一個文檔字符串http://www.python.org/dev/peps/pep-0257/ – 2013-03-12 10:45:10

13

setter方法必須與getter具有相同的名稱。別擔心,裝飾者知道如何區分他們。

@x.setter 
def x(self, value): 
... 
6

當你調用@ x.setter,@ x.getter,或@ x.deleter,你要創建一個新的屬性和對象給它你正在裝飾的功能的名稱。所以,真正重要的是,你最後一次在類定義中使用@ x。* er裝飾器,它有你實際想要使用的名稱。但是,由於這會讓您的類名稱空間受到您希望使用的屬性的不完整版本的污染,所以最好使用相同的名稱進行清理。