Python:如何将多个参数传递给属性获取器?

| 考虑以下示例:
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
叫with4ѭ 这将引发TypeError:
\'int\' object is not callable
,这很正常,因为我们的
x
被评估为evaluated2ѭ。 因此,我想知道如果可能的话,如何将一个参数传递给属性获取器。
已邀请:
请注意,您不必使用ѭ8作为装饰器。您可以很高兴地以旧方式使用它,并公开除属性外的各个方法:
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
根据您使用的确切方式,这可能不是一个好主意(但是,如果我在所检查的任何代码中都遇到此模式,我希望在注释中看到一个很好的理由)
我认为您没有完全了解属性的用途。 如果创建属性
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
属性应仅取决于相关对象。如果要使用一些外部参数,则应使用方法。
在第二个示例中,您正在使用
a.x()
,就好像它是一个函数:
a.x(neg=True)
。考虑到这一点,为什么不仅仅将其定义为一个函数呢?
我知道这个问题很旧,但是作为参考,您可以使用类似这样的参数来调用属性:
a = A()
assert a.x == 5
assert A.x.fget(a, True) == -5
正如其他人提到的那样,不建议这样做。
在这种特殊情况下,您可以定义两个属性,它们调用一个基础函数:
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
我刚遇到这个问题。我有类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()

要回复问题请先登录注册