getter 和 setter 的 Google 样式指南属性

2024-04-02

我对其中的一项建议感到好奇有关属性的 Google Python 风格指南 https://google.github.io/styleguide/pyguide.html#Properties.

他们在其中给出了以下示例:

class Square(object):
    """A square with two properties: a writable area and a read-only perimeter.

    To use:
    >>> sq = Square(3)
    >>> sq.area
    9
    >>> sq.perimeter
    12
    >>> sq.area = 16
    >>> sq.side
    4
    >>> sq.perimeter
    16
    """

    def __init__(self, side):
         self.side = side

    def __get_area(self):
        """Calculates the 'area' property."""
        return self.side ** 2

    def ___get_area(self):
        """Indirect accessor for 'area' property."""
        return self.__get_area()

    def __set_area(self, area):
        """Sets the 'area' property."""
        self.side = math.sqrt(area)

    def ___set_area(self, area):
        """Indirect setter for 'area' property."""
        self.__set_area(area)

    area = property(___get_area, ___set_area,
                    doc="""Gets or sets the area of the square.""")

    @property
    def perimeter(self):
        return self.side * 4

我对此有两个问题:

  1. 使用三个下划线“间接”有什么好处___get_area and ___set_area以及两个下划线,而不是直接使用两个下划线?

  2. Why use property()作为具有这组双下划线和三重下划线方法的方法,而不是执行以下操作:

    @property
    def area(self):
        return self.side ** 2
    
    @area.setter
    def area(self, value):
        self.side = math.sqrt(value)
    

在风格指南中他们确实给出了一个原因:

如果属性本身没有被覆盖,则属性的继承可能是不明显的。因此,必须确保间接调用访问器方法,以确保属性调用子类中重写的方法(使用模板方法 DP)。

(where 模板法DP is the 模板方法设计模式 http://www.aleax.it/Python/os03_template_dp.pdf(幻灯片由 Google 的杰出 Pythonista Alex Martelli 提供)。

所以他们想给子类机会覆盖实现,并给property三下划线版本来调用双下划线方法,以便您可以覆盖它们。在这种情况下,你必须拼写出损坏的名称:

class WonkySquare(Square):
    def _Square__get_area(self):
        return self.square ** 2 + 0.5

显然,提出这个方案的人从来不知道你可以重写属性的 getter 或 setter,请参阅Python 重写 getter 而不使用 setter https://stackoverflow.com/questions/15785982/python-overriding-getter-without-setter:

class ProperlySubclassedSquare(Square):
    @Square.area.getter
    def area(self):
        return self.square ** 2 + (0.5 - 0.5)

话又说回来,getter, setter and deleter装饰器属性仅在 Python 2.6 中添加。样式指南必须是为较旧的 Python 版本编写的。

对于 2.6 及更高版本,请坚持@propname.setter图案代替。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

getter 和 setter 的 Google 样式指南属性 的相关文章

随机推荐