Skip to content

属性与描述符:@property与属性验证 ​

@property装饰器 ​

python
class Circle:
    def __init__(self, radius):
        self._radius = radius
    
    @property
    def radius(self):
        return self._radius
    
    @radius.setter
    def radius(self, value):
        if value < 0:
            raise ValueError("Radius must be positive")
        self._radius = value
    
    @property
    def area(self):
        return 3.14159 * self._radius ** 2

c = Circle(5)
print(c.radius)  # 5
print(c.area)    # 78.53975
c.radius = 10
# c.radius = -1  # ValueError

描述符协议 ​

python
class Validator:
    def __init__(self, min_value=None):
        self.min_value = min_value
    
    def __set_name__(self, owner, name):
        self.name = name
    
    def __get__(self, obj, objtype=None):
        if obj is None:
            return self
        return obj.__dict__.get(self.name)
    
    def __set__(self, obj, value):
        if self.min_value is not None and value < self.min_value:
            raise ValueError(f"{self.name} must be >= {self.min_value}")
        obj.__dict__[self.name] = value

class Account:
    balance = Validator(min_value=0)
    
    def __init__(self, balance):
        self.balance = balance

acc = Account(100)
acc.balance = 50
# acc.balance = -10  # ValueError

练习 ​

  1. 温度转换:用@property实现Fahrenheit和Celsius互转。
  2. 只读属性:实现只有getter没有setter的属性。
  3. 描述符验证器:实现email格式验证描述符。

答案:第四章答案

下一节:数据类

用心记录每一步成长