欢迎光临
我们一直在努力

Python中的装饰器@property用法总结

文章目录

      • 一、核心作用
      • 二、基本用法
        • 1. 只读属性(仅获取)
        • 2. 可读可写属性(`@属性名.setter`)
        • 3. 可删除属性(`@属性名.deleter`)
      • 三、与普通属性的区别
      • 四、高级应用场景
        • 1. 缓存计算结果
        • 2. 兼容旧接口
      • 五、注意事项
      • 总结

@property是Python中的装饰器,用于将类的方法转换为
属性(即“特性”),让方法可以像普通属性一样被访问和赋值,同时支持在访问/赋值时添加自定义逻辑(如数据校验、计算、缓存等),实现对属性的精细化控制。

一、核心作用

  • 方法属性化:将方法伪装成属性,调用时无需加括号(obj.attr而非obj.attr());
  • 控制访问逻辑:在属性读取、赋值、删除时插入自定义代码(如校验、计算);
  • 兼容原有接口:在不修改外部调用方式的前提下,重构属性的实现逻辑。
  • 二、基本用法

    1. 只读属性(仅获取)

    将方法装饰为只读属性,实现“计算属性”(值动态生成)。

    class Circle:
    def __init__(self, radius):
    self.radius = radius

    @property
    def area(self):
    """计算圆的面积(只读属性)"""
    return 3.14159 * self.radius **2

    # 使用
    c = Circle(5)
    print(c.area) # 无需加括号,直接访问 → 78.53975
    # c.area = 100 # 报错:无法赋值(只读)

    2. 可读可写属性(@属性名.setter)

    通过@属性名.setter装饰器定义赋值逻辑,实现属性的写控制(如数据校验)。

    class Person:
    def __init__(self, name):
    self._name = name # 私有变量(约定用下划线标识)

    @property
    def name(self):
    """获取name属性"""
    return self._name

    @name.setter
    def name(self, value):
    """设置name属性(添加校验)"""
    if not isinstance(value, str):
    raise TypeError("name必须是字符串")
    if len(value) < 2:
    raise ValueError("name长度不能小于2")
    self._name = value

    # 使用
    p = Person("Alice")
    print(p.name) # 获取 → Alice

    p.name = "Bob" # 赋值(触发setter)
    print(p.name) # Bob

    # p.name = 123 # 触发TypeError
    # p.name = "A" # 触发ValueError

    3. 可删除属性(@属性名.deleter)

    通过@属性名.deleter装饰器定义删除逻辑,控制del obj.attr的行为。

    class Person:
    def __init__(self, age):
    self._age = age

    @property
    def age(self):
    return self._age

    @age.deleter
    def age(self):
    """删除age属性时的逻辑"""
    print("删除age属性")
    del self._age

    # 使用
    p = Person(25)
    del p.age # 触发deleter → 打印"删除age属性"
    # print(p.age) # 报错:_age已被删除

    三、与普通属性的区别

    特性普通属性@property装饰的属性
    访问方式 直接访问(obj.attr) 直接访问(obj.attr)
    底层逻辑 简单赋值/读取 可嵌入自定义逻辑(校验、计算)
    可变性 默认可读可写 可控制为只读/可写/可删除
    动态性 固定值 可动态计算(如面积、年龄)

    四、高级应用场景

    1. 缓存计算结果

    对耗时的计算属性缓存结果,避免重复计算:

    class Rectangle:
    def __init__(self, width, height):
    self.width = width
    self.height = height
    self._area = None # 缓存面积

    @property
    def area(self):
    if self._area is None:
    print("计算面积…")
    self._area = self.width * self.height
    return self._area

    # 使用
    r = Rectangle(3, 4)
    print(r.area) # 计算面积… → 12(首次计算并缓存)
    print(r.area) # 12(直接读取缓存)

    2. 兼容旧接口

    重构类时,将原有方法改为属性,不影响外部调用:

    # 旧版本:通过方法获取姓名
    class User:
    def get_name(self):
    return self._name

    # 新版本:用@property兼容
    class User:
    def __init__(self, name):
    self._name = name

    @property
    def name(self):
    return self._name

    # 外部调用:从`user.get_name()`改为`user.name`,更简洁

    五、注意事项

  • 命名规范:内部存储的变量通常用下划线开头(如_name),避免与@property装饰的属性名冲突;
  • 只读属性:仅定义@property而不定义setter,则属性为只读;
  • 性能:若属性逻辑复杂(如大量计算),需注意性能开销(可结合缓存);
  • 与__dict__的关系:@property定义的属性不会出现在实例的__dict__中(存储在类的__dict__)。
  • 总结

    @property是Python实现“受控属性”的核心工具,既能让代码更简洁(方法属性化),又能灵活控制属性的读取、赋值和删除逻辑,广泛用于数据校验、动态计算、接口兼容等场景。

    赞(0)
    未经允许不得转载:171主机测评 » Python中的装饰器@property用法总结
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址