Google Style Guide properties for getters and setters
我对google python风格指南中关于属性的一个建议很好奇。
其中,他们给出了以下示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | 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 2 3 4 5 6 7 | @property def area(self): return self.side ** 2 @area.setter def area(self, value): self.side = math.sqrt(value) |
在样式指南中,他们给出了一个原因:
Inheritance with properties can be non-obvious if the property itself is not overridden. Thus one must make sure that accessor methods are called indirectly to ensure methods overridden in subclasses are called by the property (using the Template Method DP).
(模板方法dp是模板方法设计模式(Alex Martelli的幻灯片,谷歌的pythonista Extraordinaire)。
因此,它们希望给子类机会重写实现,并给
1 2 3 | class WonkySquare(Square): def _Square__get_area(self): return self.square ** 2 + 0.5 |
显然,提出此方案的人从来就不知道您可以只覆盖属性的getter或setter,请参见python overriding getter without setter:
1 2 3 4 | class ProperlySubclassedSquare(Square): @Square.area.getter def area(self): return self.square ** 2 + (0.5 - 0.5) |
然后,在python 2.6中只添加了
对于2.6及更高版本,请遵循