2011-04-19 67 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 

正如别人提到的,这是不建议。