当前位置: 首页 > news >正文

Python:property装饰器的作用

@property 装饰器可以将方法转换为属性,便于对属性的访问控制。

class Person:
    def __init__(self, name):
        self._name = name  # 设为受保护属性(单下划线约定)

    @property               # 将方法转换为属性的 getter
    def name(self):
        return self._name  # 实际返回的是受保护属性

    @name.setter            # 定义属性的 setter
    def name(self, value):
        if len(value) >= 2:
            self._name = value
        else:
            raise ValueError("Name is too short")

person = Person("Alice")
print(person.name)  # 输出:Alice

person.name = "Bob"
print(person.name)  # 输出:Bob

关键:

  • 使用 @property 可以在不改变调用方式的情况下,对属性的访问进行控制。
  • 可以在 setter 方法中添加验证逻辑。

二、核心机制

1. 将方法伪装成属性访问
  • 普通方法调用:通常需要 obj.method() 的形式

  • @property 魔法:让方法可以通过 obj.property 直接访问

person = Person("Alice")
print(person.name)  # 看起来像访问属性,实际调用了 @property 修饰的 name() 方法
2. 实现访问控制
  • Setter 验证:通过 @name.setter 控制赋值逻辑

person.name = "B"  # 触发 setter,因长度不足抛出 ValueError
3. 隐藏底层存储
  • 数据实际存储在 self._name

  • 外部使用者只感知 name 属性,不知内部实现细节

print(person.__dict__)  # 输出:{'_name': 'Bob'}(真实存储位置)

三、@property 的作用总结

特性说明
属性化方法调用用 obj.property 替代 obj.method(),更符合直觉
数据验证在 setter 中检查数据合法性(如类型、范围、格式)
访问隔离外部不直接操作实际存储的 _name,保护数据完整性
动态计算属性getter 可以实时计算值(例如根据其他属性生成结果)
接口兼容性后续修改 _name 的存储方式时,外部调用接口无需变更

四、对比直接操作属性

没有 @property 的问题
class Person:
    def __init__(self, name):
        self.name = name  # 直接暴露属性

# 外部可以随意设置非法值
person = Person("A")  # 短名字直接通过,没有验证

 使用 @property 的优势

person = Person("Alice")
person.name = "A"  # 自动触发 setter 验证,抛出 ValueError

五、进阶用法

1. 只读属性(无 setter)
class Circle:
    def __init__(self, radius):
        self.radius = radius

    @property
    def diameter(self):
        return self.radius * 2  # 动态计算,无法直接修改

circle = Circle(5)
print(circle.diameter)  # 输出:10
circle.diameter = 20    # 报错:AttributeError(没有 setter)

 2. 删除控制@xxx.deleter

class File:
    def __init__(self, path):
        self.path = path

    @property
    def path(self):
        return self._path

    @path.deleter
    def path(self):
        print("删除前清理资源")
        del self._path

file = File("test.txt")
del file.path  # 触发 deleter
3. 与私有属性配合
class SafeData:
    def __init__(self):
        self.__secret = 42  # 私有属性

    @property
    def secret(self):
        # 可在此处添加访问日志、权限验证等
        return self.__secret * 2  # 返回加工后的数据

data = SafeData()
print(data.secret)  # 输出:84(外部无法直接访问 __secret)

相关文章:

  • Python--数据类型(下)
  • 【mysql80 安装】mysql8.0.31 安装修改3306端口
  • 【个人开源】——从零开始在高通手机上部署sd(一)
  • Python开源项目月排行 2024年12月
  • 数据结构与算法:奇校验与偶校验
  • 机器视觉3D中,深度图与点云图数据对比分析
  • 【深度学习】Pytorch的深入理解和研究
  • 目的NAT(NAT Server)
  • [实现Rpc] Dispatcher类的实现 | 开闭原则 | 测试 | 传gitee
  • Jupyter里面的manim编程学习
  • Simulink库浏览器中有大量的模型组件工具箱介绍
  • Python应用算法之贪心算法理解和实践
  • 站长工具SEO综合查询是什么?怎么利用站长工具SEO综合查询
  • 第8章:LangChain检索增强生成RAG--2.2Core RAG APIs
  • 《A++ 敏捷开发》- 16 评审与结对编程
  • PyTorch gather 方法详解:作用、应用场景与示例解析(中英双语)
  • 小米手环7屏幕脱胶维修
  • javaSE学习笔记24-注解(annotation)
  • SBOM情报预警 | 恶意NPM组件窃取Solana智能合约私钥
  • Docket Desktop 安装redis 并设置密码
  • 以色列高等法院裁定政府解职辛贝特局长程序不当
  • 中方是否支持或参加俄乌谈判?外交部:支持一切有利于和平的努力
  • 新华社原香港分社副社长、深圳市委原副书记秦文俊逝世
  • 甘肃省白银市一煤矿发生透水事故,3人失联
  • 马上评|房屋“注胶堵漏”骗局何以屡屡得逞
  • 证监会副主席李明:支持符合条件的外资机构申请新业务、设立新产品