【问题标题】:Properties defined with property() and @property [closed]用 property() 和 @property 定义的属性 [关闭]
【发布时间】:2016-10-12 16:45:32
【问题描述】:

我现在正在尝试正确地学习 Python,我对存在两种创建对象属性的方法感到非常困惑:使用@property 装饰器和property() 方法。所以以下两个都是有效的:

class MyClassAt:
    def __init__(self, value):
        self._time = value

    @property
    def time(self):
        return self._time

    @time.setter
    def time(self, value):
        if value > 0:
            self._time = value
        else:
            raise ValueError('Time should be positive')

class MyClassNoAt:
    def __init__(self, value):
        self._time = value

    def get_time(self):
        return self._time

    def set_time(self, value):
        if value > 0:
            self._time = value
        else:
            raise ValueError('Time should be positive')

    time = property(fget=get_time, fset=set_time)

是否有使用哪个协议? Pythonista 会选择什么?

【问题讨论】:

  • 两者是等价的。第一种形式肯定更常见。
  • 首选第一种形式。在第二种形式中,您公开了两个额外的方法,set_timeget_time,它们现在是您的公共 api 的一部分,并且具有单独的 set 和 get 方法违背了属性的目的。
  • @property 完全一样,只是使用property() 对象作为装饰器。尽可能使用装饰器表单。
  • 大家都说应该用第一种形式。所以有协议,没有“意见”。这个问题仍然被投票以基于意见的方式结束。虽然我没有问“你喜欢哪个”,而是“如果有协议”。无论如何,谢谢大家的回答。
  • 是的,我同意。询问为什么有两种语法以及何时使用一种而不是另一种的原因并不是基于意见的。

标签: python oop


【解决方案1】:

它们是等价的,但第一个是首选,因为许多人发现它更具可读性(同时也不会弄乱代码命名空间)。 第二种方法的问题在于,您定义了两个永远不会使用的方法,并且它们保留在类中。

只有当他们必须支持非常旧的 Python 版本时才会使用第二种方法,该版本不支持装饰器语法糖。函数和方法装饰器是在 Python 2.4 中添加的(而类装饰器仅在 2.6 版本中),因此几乎在所有情况下都已成为过去的问题。

【讨论】:

    【解决方案2】:

    在过去(python 2.4 之前),装饰器语法(即@property)还不存在,因此创建装饰函数的唯一方法是使用第二种方法

    time = property(fget=get_time, fset=set_time)
    

    PEP that lead to decorators 为新语法背后的动机提供了许多原因,但也许最重要的是这一点。

    将转换应用于函数的当前方法或 方法将实际转换放在函数体之后。为了 大型函数,这将函数的关键组件分开 来自函数其余部分外部定义的行为 界面。

    使用较新的@ 语法可以更清楚地了解属性的存在,只需浏览代码并查看方法/属性定义即可。

    不幸的是,当他们第一次添加新的@property 装饰器时,它只能用于装饰 getter。如果您有 setterdeleter 函数,您仍然必须使用旧语法。

    幸运的是,在 Python 2.6 中,他们为属性添加了 gettersetterdeleter 属性,因此您可以对所有属性使用新语法。

    如今,真的没有理由使用旧语法来装饰函数和类。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-31
      • 2014-03-06
      • 2016-03-17
      • 1970-01-01
      相关资源
      最近更新 更多