1. class Person:
  2. def __init__(self, first_name):
  3. self.first_name = first_name # 等价于 self.first_name(first_name)
  4. @property # 将 first_name() 变为实例的一个属性
  5. def first_name(self):
  6. return self._first_name
  7. @first_name.setter
  8. def first_name(self, value):
  9. if not isinstance(value, str):
  10. raise TypeError('Expected a string')
  11. self._first_name = value
  12. @first_name.deleter
  13. def first_name(self):
  14. raise AttributeError("Can't delete attribute")
  15. p = Person('Ming')
  16. print(p.first_name) # 实际调用的是 p.first_name()
  17. p.first_name = '42'
  18. print(p.first_name)
  19. >>> Ming
  20. >>> 42
  1. # 更易用的接口
  2. mport math
  3. class Circle:
  4. def __init__(self, radius):
  5. self.radius = radius
  6. @property
  7. def area(self):
  8. return math.pi * self.radius ** 2
  9. @property
  10. def diameter(self):
  11. return self.radius * 2
  12. @property
  13. def perimeter(self):
  14. return 2 * math.pi * self.radius
  15. c = Circle(4.0)
  16. print(c.area)
  17. print(c.diameter)
  18. print(c.perimeter)

总结: property 将实例的方法(a.method())转为属性(a.method)的方式调用, 可以通过被 property 装饰的函数名.setter/deleter 修改/删除实例属性(可以对其进行额外验证, 比如修改的参数必须为字符串, 禁止删除属性等等).

如果只是普通的类, 不需要进行修改实例属性的验证, 那么不应该使用 property.
如果只设置 @property 则相当于将实例属性设置为 只读(read only), 实例属性将无法修改或删除.