Python:如何将多个参数传递给属性getter?

Riz*_*izo 55 python language-features properties

请考虑以下示例:

class A:
    @property
    def x(self): return 5
Run Code Online (Sandbox Code Playgroud)

所以,当然要求a = A(); a.x回归5

但想象一下,您希望能够修改属性x.
这样,例如:

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

并称之为 a = A(); a.x(neg=True)

这将引发一个TypeError:,'int' object is not callable这很正常,因为我们x被评估为5.

所以,我想知道如果可能的话,如何将多于一个参数传递给属性getter.

nco*_*lan 60

请注意,您不具备使用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
Run Code Online (Sandbox Code Playgroud)

这可能是一个好主意,也可能不是一个好主意,具体取决于你正在做什么(但如果我在我正在审查的任何代码中遇到这种模式,我希望在评论中看到一个很好的理由)

  • 这里不存在封装的想法。以这种方式使用 getter 是没有意义的。那里的接口坏了。 (2认同)
  • 我会使用“@property def x(self): return self.get_x()”来代替“x = property(get_x)”。更具可读性。 (2认同)

Thi*_*ter 35

我认为你并没有完全理解财产的目的.

如果您创建了一个属性x,那么您将使用obj.x而不是使用它来访问它obj.x().创建属性后,不可能直接调用底层函数.

如果要传递参数,请为方法命名get_x,不要将其设为属性:

def get_x(self, neg=False):
    return 5 if not neg else -5
Run Code Online (Sandbox Code Playgroud)

如果你想创建一个setter,那就这样做:

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

    @x.setter
    def x(self, value): self._x = value
Run Code Online (Sandbox Code Playgroud)

  • @Rizo:属性不是为此设计的. (7认同)

小智 16

属性应仅依赖于相关对象.如果要使用某些外部参数,则应使用方法.


NPE*_*NPE 11

在你的第二个例子中,你正在使用a.x()它就好像它是一个函数:a.x(neg=True).考虑到这一点,为什么不将它定义为一个函数呢?

  • @Rizo为什么?如果您希望它像函数一样运行,则使用函数(方法).但是在回答你的问题时,唯一的办法就是从带参数的属性中返回一个callable.那么你会看到一些看起来完全像功能但效率低下的东西. (4认同)
  • 如果getter除了返回一个简单的值(或默认值)之外什么都不做,那么它不再是一个"getter",而是一个常规函数. (4认同)
  • @Rizo:在你给出的例子中,让*调用者*决定如何处理返回值可能更明智.毕竟是*来电者*在条件下通过. (2认同)

Cam*_*mpi 6

我知道这个问题很旧,但是作为参考,您可以使用类似这样的参数来调用属性:

a = A()
assert a.x == 5
assert A.x.fget(a, True) == -5
Run Code Online (Sandbox Code Playgroud)

正如其他人提到的那样,不建议这样做。