class Person:def __init__(self, first_name):self.first_name = first_name # 等价于 self.first_name(first_name)@property # 将 first_name() 变为实例的一个属性def first_name(self):return self._first_name@first_name.setterdef first_name(self, value):if not isinstance(value, str):raise TypeError('Expected a string')self._first_name = value@first_name.deleterdef first_name(self):raise AttributeError("Can't delete attribute")p = Person('Ming')print(p.first_name) # 实际调用的是 p.first_name()p.first_name = '42'print(p.first_name)>>> Ming>>> 42
# 更易用的接口mport mathclass Circle:def __init__(self, radius):self.radius = radius@propertydef area(self):return math.pi * self.radius ** 2@propertydef diameter(self):return self.radius * 2@propertydef perimeter(self):return 2 * math.pi * self.radiusc = Circle(4.0)print(c.area)print(c.diameter)print(c.perimeter)
总结: property 将实例的方法(a.method())转为属性(a.method)的方式调用, 可以通过被 property 装饰的函数名.setter/deleter 修改/删除实例属性(可以对其进行额外验证, 比如修改的参数必须为字符串, 禁止删除属性等等).
如果只是普通的类, 不需要进行修改实例属性的验证, 那么不应该使用 property.
如果只设置 @property 则相当于将实例属性设置为 只读(read only), 实例属性将无法修改或删除.
