代码之家  ›  专栏  ›  技术社区  ›  corvus

我应该何时为python属性定义getter方法?

  •  2
  • corvus  · 技术社区  · 4 年前

    我对python的实用性有点困惑 @*.getter

    为了研究这个问题,让我们编写一个非常简单的类:

    class Foo:
    
        def __init__(self):
        
            self._x = None
    
        @property
        def x(self):
            print('Attribute `self.x` is a property.')
            return self._x
    
        @x.getter
        def x(self):
            print('Getting property `x`...')
            return self._x
    

    现在,如果我尝试实例化这个类并获取属性 x

    >>> A = Foo()
    >>> print(A.x)
    Getting property `x`...
    None
    

    好吧,那又怎样?这正是我们应该期待的。

    但是,如果我定义了完全相同的类 没有

    >>> print(A.x)
    Attribute `self.x` is a property.
    None
    

    当没有定义getter方法时,尝试检索属性会导致“property definition method”(我指的是在下面定义的方法) @property ,因为没有更好的名字)取而代之。

    有趣的是,在第一种情况下 @财产 从来没有真正叫过。

    最后,有没有使用比下面的规范形式更复杂的属性定义方法,同时还使用 方法?

    @property
    def x(self): return self._x
    
    0 回复  |  直到 4 年前
        1
  •  1
  •   Grismar    4 年前

    使用 @x.getter decorator告诉Python下面的方法是属性的预期getter。

    你说得对,在你举的例子中,它不是很有用。这个 @property decorator做同样的工作,一次定义属性。在单个类定义中确实没有理由同时使用这两者。

    但是,也许您想重写子类中的getter方法?

    class Foo:
        def __init__(self, x):
            self._x = x
    
        @property
        def x(self):
            print('Attribute `self.x` is a property.')
            return self._x
    
    
    class Bar(Foo):
        count: int = 0
    
        @Foo.x.getter
        def x(self):
            Bar.count += 1
            print(f'Getting Bar property `x` ({Bar.count})')
            return self._x
    
    
    foo = Foo(10)
    print(foo.x)
    bar = Bar(10)
    print(bar.x)
    print(bar.x)
    

    Attribute `self.x` is a property.
    10
    Getting Bar property `x` (1)
    10
    Getting Bar property `x` (2)
    10
    

    在其他几个用例中,显式定义getter是有意义的,即使在基本用例中您只使用getter @财产 @attr.setter

    计数器只是为了说明一个简单的原因,说明为什么您可能希望修改getter行为,即使它不修改属性的实际值。