2011-04-19 69 views
31

請看下面的例子:Python:如何將多個參數傳遞給屬性getter?

class A: 
    @property 
    def x(self): return 5 

所以,當然調用a = A(); a.x將返回5

但是想象一下,你希望能夠修改屬性x。
這種方式,例如:

class A: 
    @property 
    def x(self, neg = False): return 5 if not neg else -5 

而且隨着a = A(); a.x(neg=True)

這將引發TypeError調用它:'int' object is not callable,這是很正常的,因爲我們的x作爲5評估。

所以,我想知道如何將更多的參數傳遞給屬性獲取器,如果可能的話。

回答

37

請注意,您不要使用property作爲裝飾。你可以很愉快地使用舊的方式,揭露除個人財產的方法:

class A: 
    def get_x(self, neg=False): 
     return -5 if neg else 5 
    x = property(get_x) 

>>> a = A() 
>>> a.x 
5 
>>> a.get_x() 
5 
>>> a.get_x(True) 
-5 

這可能也取決於可能不是一個好主意,正是你用它做(但我如果我在審查過的任何代碼中遇到這種模式,我希望在評論中看到很好的理由)

24

我想你並沒有完全理解屬性的目的。

如果您創建了一個屬性x,您將使用obj.x而不是obj.x()來訪問它。 創建屬性後,直接調用底層函數並不容易。

如果你想傳遞參數,命名方法get_x,不要使一個屬性:

def get_x(self, neg=False): 
    return 5 if not neg else -5 

如果你想創建一個二傳手,像這樣做:

class A: 
    @property 
    def x(self): return 5 

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

我知道!你可以在我的第一個例子中看到'a.x'調用。 – Rizo 2011-04-19 11:31:22

+1

@Rizo:屬性不是爲此設計的。 – XORcist 2011-04-19 11:46:57

7

在你的第二個例子中,你使用a.x()就好像它是一個函數:a.x(neg=True)。考慮到這一點,爲什麼不把它定義爲一個函數呢?

+0

這是一個直接的解決方案,但我使用非常複雜的getter和setter,並希望繼續使用它們而不必爲屬性編寫單獨的函數。 – Rizo 2011-04-19 11:34:15

+0

這不回答我的問題。我現在可以在python中使用函數了! :)我只是想知道是否有某種方法來強制一個屬性作爲一個函數。 – Rizo 2011-04-19 11:41:06

+3

@Rizo爲什麼?如果你希望它像一個函數,然後使用一個函數(方法)。但是在回答你的問題時,唯一的方法是從具有參數的屬性返回可調用對象。然後你會看到一些看起來完全像功能但效率不高的東西。 – Keith 2011-04-19 11:47:12

6

屬性應該只取決於相關對象。如果你想使用一些外部參數,你應該使用方法。

0

我知道這個問題很陳舊,但作爲參考,您可以使用如下參數調用屬性:

a = A() 
assert a.x == 5 
assert A.x.fget(a, True) == -5 

正如別人提到的,這是不建議。