考虑以下示例:
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
。
所以,我想知道如果可能的话,如何将多于一个参数传递给属性getter。
答案 0 :(得分:50)
请注意,您 不能将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
这可能是一个好主意,也可能不是一个好主意,具体取决于你正在做什么(但如果我在我正在审查的任何代码中遇到这种模式,我希望在评论中看到一个很好的理由)< / p>
答案 1 :(得分:32)
我认为你并没有完全理解财产的目的。
如果您创建了一个属性x
,则可以使用obj.x
代替obj.x()
来访问该属性。
创建属性后,不可能直接调用底层函数。
如果要传递参数,请为方法命名get_x
,不要将其设为属性:
def get_x(self, neg=False):
return 5 if not neg else -5
如果你想创建一个setter,可以这样做:
class A:
@property
def x(self): return 5
@x.setter
def x(self, value): self._x = value
答案 2 :(得分:16)
属性应仅依赖于相关对象。如果要使用某些外部参数,则应使用方法。
答案 3 :(得分:11)
在第二个示例中,您使用的是a.x()
,就好像它是一个函数:a.x(neg=True)
。考虑到这一点,为什么不将它定义为函数?
答案 4 :(得分:5)
我知道这个问题很旧,但是,作为参考,您可以使用这样的参数调用您的属性:
a = A()
assert a.x == 5
assert A.x.fget(a, True) == -5
正如其他人提到的那样,不建议这样做。
答案 5 :(得分:3)
在这种特殊情况下,您可以定义两个属性,它们调用一个基础函数:
class A:
@property
def x(self):
return self._x(neg = False)
@property
def x_neg(self):
return self._x(neg = True)
def _x(self, neg):
return 5 if not neg else -5
答案 6 :(得分:0)
我刚遇到这个问题。我有类Polynomial(),并且正在定义一个渐变,如果没有参数,我想返回一个函数或评估是否有参数。我想将渐变存储为属性,因此我不需要每次使用时都计算它,并且我想使用@property以便渐变计算延迟。我的解决方案是定义一个带有定义的调用方法的Gradient类,以使Polynomial的grad属性返回。
@property
def grad(self):
"""
returns gradient vector
"""
class Gradient(list):
def __call__(self, *args, **kwargs):
res = []
for partial_derivative in g:
res.append(partial_derivative(*args, **kwargs))
return res
g = Gradient()
for i in range(1, len(self.term_matrix[0])):
g.append(self.derivative(self.term_matrix[0][i]))
return g
然后我成功通过了以下测试:
def test_gradient(self):
f = Polynomial('x^2y + y^3 + xy^3')
self.assertEqual(f.grad, [Polynomial('2xy + y^3'), Polynomial('x^2 + 3xy^2 + 3y^2')])
self.assertEqual(f.grad(x=1, y=2), [12, 25])
f = Polynomial('x^2')
self.assertEqual(f.grad(1), [2])
因此,对于这个问题,我们可以尝试:
class A:
@property
def x(self):
class ReturnClass(int):
def __call__(self, neg=False):
if not neg:
return 5
return -5
return ReturnClass()