我应该使用属性还是 getter 和 setter?

deb*_*ish 6 python properties getter-setter python-3.x

我知道在python中使用getter和setter不是pythonic。而是应该使用属性装饰器。但我想知道以下场景 -

我有一个用几个实例属性初始化的类。然后稍后我需要向类添加其他实例属性。如果我不使用setter,那么我必须object.attribute = value在课外到处写。该类将没有self.attribute代码。当我需要跟踪类的属性时,这会不会成为问题(因为它们散布在类之外的代码中)?

Zer*_*eus 7

一般来说,你甚至不应该使用属性。简单属性在绝大多数情况下都可以正常工作:

class X:
    pass
Run Code Online (Sandbox Code Playgroud)

>>> x = X()
>>> x.a
Traceback (most recent call last):
  # ... etc
AttributeError: 'X' object has no attribute 'a'
>>> x.a = 'foo'
>>> x.a
'foo'
Run Code Online (Sandbox Code Playgroud)

只有在访问属性时需要做一些工作时才应该使用属性:

import random

class X:

    @property
    def a(self):
        return random.random()
Run Code Online (Sandbox Code Playgroud)

>>> x = X()
>>> x.a
0.8467160913203089
Run Code Online (Sandbox Code Playgroud)

如果您还需要能够分配给一个属性,定义一个 setter 很简单:

class X:

    @property
    def a(self):
        # do something clever
        return self._a

    @a.setter
    def a(self, value):
        # do something even cleverer
        self._a = value
Run Code Online (Sandbox Code Playgroud)

>>> x = X()
>>> x.a
Traceback (most recent call last):
  # ... etc
AttributeError: 'X' object has no attribute '_a'
>>> x.a = 'foo'
>>> x.a
'foo'
Run Code Online (Sandbox Code Playgroud)

请注意,在每种情况下,客户端代码访问属性或属性的方式都完全相同。没有必要让你的类“面向未来”,以防止在某些时候你可能想要做一些比简单的属性访问更复杂的事情,所以没有理由编写属性、getter 或 setter,除非你现在确实需要它们

有关惯用 Python 与其他一些语言在属性、getter 和 setter 方面的差异的更多信息,请参阅:

  • @guy 如果没有 setter,属性从外部看起来确实像是只读属性,但这不是它的 *for*,事实上,故意将属性设为只读的想法违背了 Python 的“同意成年人”的理念任何状况之下。正如您所说,属性用于在访问它们时需要进行一些计算的属性。关于它们的目的和使用的完整教程超出了本答案的范围;除了我已经给出的链接,也许[这篇文章](https://www.blog.pythonlibrary.org/2014/01/20/python-201-properties/) 对你有用。 (2认同)