Python property装饰器详解
Pythonproperty装饰器详解property是 Python 中用于实现属性访问控制的内置装饰器它可以让你像访问属性一样调用方法。基本概念class Person: def __init__(self, name): self._name name property def name(self): 获取姓名 return self._name name.setter def name(self, value): 设置姓名 if not isinstance(value, str): raise TypeError(姓名必须是字符串) self._name value name.deleter def name(self): 删除姓名 del self._name # 使用示例 p Person(张三) print(p.name) # 张三 - 像属性一样访问 p.name 李四 # 像属性一样赋值 print(p.name) # 李四 del p.name # 像属性一样删除三种装饰器1.property- getterclass Circle: def __init__(self, radius): self._radius radius property def radius(self): 获取半径 return self._radius property def area(self): 计算面积 - 只读属性 return 3.14159 * self._radius ** 2 c Circle(5) print(c.radius) # 5 print(c.area) # 78.53975 # c.area 100 # 错误AttributeError: cant set attribute2.方法名.setter- setterclass Temperature: def __init__(self, celsius0): self._celsius celsius property def celsius(self): return self._celsius celsius.setter def celsius(self, value): if value -273.15: raise ValueError(温度不能低于绝对零度) self._celsius value property def fahrenheit(self): 只读属性 return self._celsius * 9/5 32 t Temperature(25) t.celsius 30 # 使用setter print(t.celsius) # 30 # t.celsius -300 # ValueError!3.方法名.deleter- deleterclass User: def __init__(self, username): self._username username self._password secret property def password(self): return self._password password.deleter def password(self): 删除密码 print(正在删除密码...) del self._password user User(alice) print(user.password) # secret del user.password # 正在删除密码... # print(user.password) # AttributeError实际应用场景1. 数据验证class Student: def __init__(self, name, age, score): self.name name self.age age self.score score property def name(self): return self._name name.setter def name(self, value): if not value or not value.strip(): raise ValueError(姓名不能为空) self._name value.strip() property def age(self): return self._age age.setter def age(self, value): if not isinstance(value, int): raise TypeError(年龄必须是整数) if value 0 or value 150: raise ValueError(年龄必须在0-150之间) self._age value property def score(self): return self._score score.setter def score(self, value): if not 0 value 100: raise ValueError(分数必须在0-100之间) self._score value property def grade(self): 只读属性 - 根据分数计算等级 if self._score 90: return A elif self._score 80: return B elif self._score 70: return C elif self._score 60: return D else: return F s Student(张三, 18, 85) print(f{s.name}, {s.age}岁, 成绩{s.score}, 等级{s.grade})2. 延迟计算/缓存class DataProcessor: def __init__(self, data): self.data data self._processed None property def processed_data(self): 延迟计算结果会被缓存 if self._processed is None: print(正在处理数据...) self._processed [x * 2 for x in self.data] return self._processed dp DataProcessor([1, 2, 3, 4, 5]) print(dp.processed_data) # 第一次正在处理数据... [2,4,6,8,10] print(dp.processed_data) # 第二次直接返回 [2,4,6,8,10]不打印3. 属性依赖更新class Rectangle: def __init__(self, width, height): self._width width self._height height self._area None property def width(self): return self._width width.setter def width(self, value): self._width value self._area None # 清除缓存 property def height(self): return self._height height.setter def height(self, value): self._height value self._area None property def area(self): if self._area is None: self._area self._width * self._height return self._area r Rectangle(5, 3) print(r.area) # 15计算 r.width 10 print(r.area) # 30重新计算使用property的优点1. 向后兼容# 最初版本 - 直接使用属性 class PersonV1: def __init__(self, name): self.name name # 后续版本 - 需要添加验证但不影响现有代码 class PersonV2: def __init__(self, name): self._name name property def name(self): return self._name name.setter def name(self, value): if not value: raise ValueError(Name cannot be empty) self._name value # 现有代码 p.name 张三 仍然可以正常工作2. 封装逻辑class BankAccount: def __init__(self, balance0): self._balance balance self._transactions [] property def balance(self): 只读属性 return self._balance def deposit(self, amount): if amount 0: raise ValueError(存款金额必须为正数) self._balance amount self._transactions.append(f存款: {amount}) def withdraw(self, amount): if amount 0: raise ValueError(取款金额必须为正数) if amount self._balance: raise ValueError(余额不足) self._balance - amount self._transactions.append(f取款: -{amount}) property def transaction_history(self): 只读属性 return self._transactions.copy() acc BankAccount(1000) acc.deposit(500) acc.withdraw(200) print(f余额: {acc.balance}) # 1300 print(f交易记录: {acc.transaction_history}) # acc.balance 9999 # 错误无法直接修改注意事项命名约定通常使用下划线前缀_表示私有属性性能考虑property方法会有轻微的性能开销不要滥用简单的属性访问不需要使用property继承行为property会被子类继承class Parent: property def value(self): return 10 class Child(Parent): property def value(self): return 20 # 可以覆盖 c Child() print(c.value) # 20总结property是 Python 中实现封装和数据验证的优雅方式它让你能够在访问属性时添加逻辑验证、计算等创建只读属性实现延迟计算保持向后兼容性提供清晰的 API 设计