【问题标题】:When should I define getter methods for python properties?什么时候应该为 python 属性定义 getter 方法?
【发布时间】:2020-08-06 01:45:11
【问题描述】:

我对 python @*.getter 语法的实用性与简单地定义没有 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,我们会看到调用了 getter 方法:

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

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

但是,如果我定义完全相同的类没有任何 getter 方法,我们会得到不同的东西:

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

当没有定义 getter 方法时,尝试检索属性会导致调用“属性定义方法”(我的意思是在 @property 下定义的方法,因为没有更好的名称)。

有趣的是,在第一种情况下,@property 下定义的方法从未真正被调用过。

那么,如果原始属性定义在没有它的情况下似乎充当了一个 getter,那么拥有一个特殊的 getter 方法有什么意义呢?除了简单地说“这是一种财产”之外,最初的定义是否还有其他用途?是否有任何其他情况会调用此方法(除了在没有 getter 的情况下检索属性)?为什么选择使用 getter 而不是简单地将其功能合并到属性定义中?

最后,是否存在使用比以下规范形式更复杂的属性定义方法,同时还使用@*.getter 方法的用例?

@property
def x(self): return self._x

【问题讨论】:

    标签: python properties


    【解决方案1】:

    使用 @x.getter 装饰器告诉 Python 以下方法是该属性的预期 getter。

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

    但是,也许您想覆盖子类中的 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 是有意义的,即使在基本情况下您只使用 @property@attr.setter

    计数器只是用来显示您可能想要修改 getter 行为的简单原因,即使它没有修改属性的实际值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-22
      • 2021-12-30
      • 1970-01-01
      • 2012-03-23
      • 2023-02-07
      • 1970-01-01
      • 2016-10-18
      • 2012-01-17
      相关资源
      最近更新 更多