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

Python自学 - property装饰器(方法变成属性)

1 Python自学 - property装饰器(方法变成属性)

1.1 property 装饰器

  在 Python 中,property 装饰器是一个非常有用的工具,它允许你将类的方法当作属性来使用,提供了一种简洁的方式来控制属性的访问、修改和删除操作。
  为什么要将类的方法当作属性来使用?
  设想一下,如果用户设置账号信息,其中至少包括用户名密码等信息,用户名使用明文保存在数据库中可能问题不太致命,但密码如果在数据库中也是使用明文保存,那将是灾难性的,参考历史上多次著名的脱库事件。使用property装饰器后,方法就可以当成属性使用,但是在读取或写入属性时,会调用方法中的逻辑,好处就是顺便对密码可以进行加密/解密,但调用者感知不到加密/解密这个过程,就像使用普通属性一样,使用方式比较友好!

1.1.1 基本用法

1.1.1.1 使用property装饰器
class Circle:
    def __init__(self, radius):
        self._radius = radius

    @property
    def radius(self):
        return self._radius


# 创建 Circle 类的实例
circle = Circle(5)
print(circle.radius)  # 这里使用 radius 方法就像使用属性一样

示例中的,@property 装饰器将 radius 方法转换为一个只读属性。当你使用 circle.radius 时,实际上是调用了 radius 方法。

1.1.1.2 使用 setter 方法

  如果需要属性可写,可以使用 @<property_name>.setter 装饰器添加一个 setter 方法。

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 cannot be negative")
        self._radius = value


# 创建 Circle 类的实例
circle = Circle(5)  #输出:5
print(circle.radius)
circle.radius = 7  # 使用 setter 方法修改半径
print(circle.radius) # 输出 7
# 尝试设置负半径,会引发异常
# circle.radius = -1

  示例中,@radius.setter 装饰器定义了一个 setter 方法,当给 circle.radius 赋值时,会调用这个 setter 方法。同时,该方法中对输入值做了验证,确保半径不为负数。

1.1.1.3 使用 deleter 方法

  使用 @<property_name>.deleter 装饰器可以添加一个 deleter 方法,用于控制属性的删除操作。

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 cannot be negative")
        self._radius = value

    @radius.deleter
    def radius(self):
        print("Deleting radius")
        del self._radius


# 创建 Circle 类的实例
circle = Circle(5)
print(circle.radius) #输出: 5
circle.radius = 7
print(circle.radius) #输出: 7
del circle.radius  # 使用 deleter 方法删除半径
# 以下会引发错误,因为半径已被删除
# print(circle.radius)

  删除属性是一个令人惊讶的操作,最好是在类的定义时设计好需要的属性,而不是在运行时删除多余的属性。

1.1.1.4 计算属性

  所谓计算属性,是该属性在类中是无定义的, 而是通过对已有的属性进行一些运算得到的,本质就是把成员方法使用property变成属性,可谓是万物皆可属性(带参数的不行,self除外)。

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

    @property
    def area(self):
        return 3.14 * self.radius ** 2


# 创建 Circle 类的实例
circle = Circle(5)
print(circle.area)  # 这里 area 是一个计算属性,每次调用时计算

注:示例中的area本质是一个成员方法,用于计算面积,使用@property将其变成了属性,美其名曰计算属性,本质就是个有返回值的方法!读者朋友可以思考下,计算属性可以使用@area.setter装饰吗?

1.1.2 使用 property 装饰器的好处

  1. 封装性
      使用 property 装饰器可以将属性的访问和修改逻辑封装在类内部,隐藏内部实现细节。例如,你可以在 setter 方法中添加验证逻辑,而外部用户只需要像操作普通属性一样操作,无需关心验证过程。
  2. 代码可读性
      将方法作为属性使用,使代码更加简洁易读,符合 Python 的简洁性原则。
  3. 向后兼容性
      如果你一开始将一个属性作为方法实现,后来决定将其变为属性,使用 property 装饰器可以保持接口的一致性,而无需修改外部代码。

1.2 总结:

  • @property:将方法转换为只读属性。

  • @<property_name>.setter:为属性添加可写功能,并添加验证或修改逻辑。

  • @<property_name>.deleter:为属性添加删除逻辑。

  • 避免在 @property 方法中进行复杂计算,因为它可能会被频繁调用,影响性能。

  • 对于需要频繁修改的属性,要谨慎使用 property 装饰器,因为它可能会使代码难以理解。


作者声明:本文用于记录和分享作者的学习心得,部分内容或示例来源豆包AI,由于本人水平有限,难免存在表达错误,欢迎交流和指教!
Copyright © 2022~2024 All rights reserved.


http://www.kler.cn/a/471672.html

相关文章:

  • MySQL时提示,服务正在启动或者停止中,请稍候片刻后再试一次
  • 企业级Java 实体对象类定义规范
  • 汽车信息安全 -- S32K1如何更新BOOT_MAC
  • 【Java项目】基于SpringBoot的【垃圾分类系统】
  • Java爬虫获取淘宝关键字API接口:技术与应用指南
  • Rust编程语言
  • 141.环形链表 142.环形链表II
  • Azure主机windows2008就地升级十步
  • torch.max和torch.softmax python max
  • hpm使用笔记————使用usb作为从机接收来自上位机的数据然后通过spi主机发送给spi从机
  • 使用 PyTorch 自定义数据集并划分训练、验证与测试集
  • Mysql--基础篇--数据类型(整数,浮点数,日期,枚举,二进制,空间类型等)
  • Jupyter Markdown样式说明
  • HTML静态网页成品作业(HTML+CSS)——婚礼婚纱网页设计制作(6个页面)
  • OSPF使能配置
  • 攻防靶场(32):两个爆破技巧 Funbox 7 EasyEnum
  • 5. 多线程(3) --- synchronized
  • 力扣经典题目之2283. 判断一个数的数字计数是否等于数位的值
  • [网络安全]DVWA之File Upload—AntSword(蚁剑)攻击姿势及解题详析合集
  • windows蓝屏以及windows补丁回滚