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.setter
def first_name(self, value):
if not isinstance(value, str):
raise TypeError('Expected a string')
self._first_name = value
@first_name.deleter
def 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 math
class Circle:
def __init__(self, radius):
self.radius = radius
@property
def area(self):
return math.pi * self.radius ** 2
@property
def diameter(self):
return self.radius * 2
@property
def perimeter(self):
return 2 * math.pi * self.radius
c = Circle(4.0)
print(c.area)
print(c.diameter)
print(c.perimeter)
总结: property 将实例的方法(a.method())转为属性(a.method)的方式调用, 可以通过被 property 装饰的函数名.setter/deleter 修改/删除实例属性(可以对其进行额外验证, 比如修改的参数必须为字符串, 禁止删除属性等等).
如果只是普通的类, 不需要进行修改实例属性的验证, 那么不应该使用 property.
如果只设置 @property 则相当于将实例属性设置为 只读(read only), 实例属性将无法修改或删除.