当前位置:首页>python>Python学习--property() 函数详解①

Python学习--property() 函数详解①

  • 2026-10-21 13:28:55
Python学习--property() 函数详解①

property() 函数是 Python 中用于创建属性访问器的内置函数,它允许你将方法作为属性来访问,实现数据封装和属性控制。

一、property() 的基本用法

1. 基本语法

property(fget=None, fset=None, fdel=None, doc=None)
  • fget: 获取属性值的方法

  • fset: 设置属性值的方法

  • fdel: 删除属性的方法

  • doc: 属性文档字符串

2. 基本示例

class Person:    def __init__(self, name):        self._name = name  # 私有属性    def get_name(self):        """获取姓名"""        print("获取姓名")        return self._name    def set_name(self, value):        """设置姓名"""        print(f"设置姓名为: {value}")        if not isinstance(value, str):            raise TypeError("姓名必须是字符串")        self._name = value    def del_name(self):        """删除姓名"""        print("删除姓名")        del self._name    # 创建属性    name = property(get_name, set_name, del_name, "姓名属性")# 使用person = Person("张三")# 获取属性(调用get_name)print(person.name)  # 输出: 张三# 设置属性(调用set_name)person.name = "李四"# 删除属性(调用del_name)del person.name# 查看文档print(Person.name.__doc__)  # 输出: 姓名属性

二、使用装饰器语法(推荐)

1. 完整的属性装饰器

class Temperature:    def __init__(self, celsius=0):        self._celsius = celsius  # 私有属性    @property    def celsius(self):        """摄氏温度(获取器)"""        print("获取摄氏温度")        return self._celsius    @celsius.setter    def celsius(self, value):        """摄氏温度(设置器)"""        print(f"设置摄氏温度为: {value}")        if value < -273.15:            raise ValueError("温度不能低于绝对零度(-273.15°C)")        self._celsius = value    @celsius.deleter    def celsius(self):        """删除摄氏温度"""        print("删除温度数据")        del self._celsius    @property    def fahrenheit(self):        """华氏温度(只读属性)"""        print("计算华氏温度")        return self._celsius * 9/5 + 32# 使用temp = Temperature(25)print(f"摄氏温度: {temp.celsius}°C")    # 调用getterprint(f"华氏温度: {temp.fahrenheit}°F") # 只读属性temp.celsius = 30  # 调用setterprint(f"修改后华氏温度: {temp.fahrenheit}°F")# temp.fahrenheit = 100  # 错误:只读属性没有setter# del temp.fahrenheit    # 错误:只读属性没有deleterdel temp.celsius  # 调用deleter

2. 实际应用示例

class BankAccount:    def __init__(self, owner, initial_balance=0):        self.owner = owner        self._balance = initial_balance        self._transactions = []    @property    def balance(self):        """账户余额(只读)"""        return self._balance    @property    def is_overdrawn(self):        """是否透支(计算属性)"""        return self._balance < 0    @property    def transaction_count(self):        """交易次数"""        return len(self._transactions)    def deposit(self, amount):        """存款"""        if amount <= 0:            raise ValueError("存款金额必须大于0")        self._balance += amount        self._transactions.append(('存款', amount))        return self._balance    def withdraw(self, amount):        """取款"""        if amount <= 0:            raise ValueError("取款金额必须大于0")        if amount > self._balance:            raise ValueError("余额不足")        self._balance -= amount        self._transactions.append(('取款', amount))        return self._balance# 使用account = BankAccount("张三", 1000)print(f"余额: {account.balance}")         # 只读属性print(f"是否透支: {account.is_overdrawn}")  # 计算属性print(f"交易次数: {account.transaction_count}")account.deposit(500)account.withdraw(200)print(f"最终余额: {account.balance}")print(f"最终交易次数: {account.transaction_count}")# account.balance = 2000  # 错误:只读属性

三、属性验证和数据保护

1. 数据验证属性

class Student:    def __init__(self, name):        self._name = name        self._age = None        self._score = None    @property    def name(self):        return self._name    @name.setter    def name(self, value):        if not isinstance(value, str):            raise TypeError("姓名必须是字符串")        if len(value.strip()) == 0:            raise ValueError("姓名不能为空")        self._name = value    @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 isinstance(value, (int, float)):            raise TypeError("成绩必须是数字")        if value < 0 or value > 100:            raise ValueError("成绩必须在0-100之间")        self._score = value    @property    def grade(self):        """计算属性:根据成绩返回等级"""        if self._score is None:            return "未评分"        elif self._score >= 90:            return "优秀"        elif self._score >= 80:            return "良好"        elif self._score >= 60:            return "及格"        else:            return "不及格"# 使用student = Student("张三")student.age = 20student.score = 85print(f"姓名: {student.name}")print(f"年龄: {student.age}")print(f"成绩: {student.score}")print(f"等级: {student.grade}")# 测试验证try:    student.age = 200  # 错误:年龄超限except ValueError as e:    print(f"错误: {e}")try:    student.score = "优秀"  # 错误:类型不匹配except TypeError as e:    print(f"错误: {e}")

2. 惰性计算属性

import mathclass Circle:    def __init__(self, radius):        self.radius = radius        self._area = None  # 缓存区域        self._circumference = None  # 缓存周长    @property    def radius(self):        return self._radius    @radius.setter    def radius(self, value):        if value <= 0:            raise ValueError("半径必须大于0")        self._radius = value        # 当半径改变时,清除缓存        self._area = None        self._circumference = None    @property    def area(self):        """惰性计算面积(缓存结果)"""        if self._area is None:            print("计算面积...")            self._area = math.pi * self._radius ** 2        return self._area    @property    def circumference(self):        """惰性计算周长(缓存结果)"""        if self._circumference is None:            print("计算周长...")            self._circumference = 2 * math.pi * self._radius        return self._circumference# 使用circle = Circle(5)print(f"半径: {circle.radius}")print(f"面积: {circle.area}")        # 第一次计算print(f"面积: {circle.area}")        # 使用缓存print(f"周长: {circle.circumference}") # 第一次计算print(f"周长: {circle.circumference}") # 使用缓存# 改变半径,缓存失效circle.radius = 10print(f"\n新面积: {circle.area}")    # 重新计算

总结

property的核心价值:

  • ✅ 数据封装:隐藏实现细节

  • ✅ 数据验证:在设置属性时进行验证

  • ✅ 计算属性:将方法作为属性访问

  • ✅ 惰性计算:延迟计算直到需要时

  • ✅ 向后兼容:可以在不改变接口的情况下修改实现

property是Python面向对象编程中非常重要的特性,合理使用可以使代码更加优雅和安全!

最新文章

随机文章