首页
技术小册
AIGC
面试刷题
技术文章
MAGENTO
云计算
视频课程
源码下载
PDF书籍
「涨薪秘籍」
登录
注册
第 13章 性能测量和大O算法分析
13.1 timeit模块
13.2 cProfile分析器
13.3 大O算法分析
13.4 大O阶
13.4.1 使用书架打比方描述大O阶
13.4.2 大O 测量的是最坏情况
13.5 确定代码的大O 阶
13.5.1 为什么低阶项和系数不重要
13.5.2 大O 分析实例
13.5.3 常见函数调用的大O 阶
13.5.4 一眼看出大O 阶
13.5.5 当n 很小时,大O并不重要,而n通常都很小
第 14章 项目实战
14.1 汉诺塔
14.1.1 汉诺塔输出
14.1.2 汉诺塔源代码
14.1.3 汉诺塔编写代码
14.2 四子棋
14.2.1 四子棋输出
14.2.2 四子棋源代码
14.2.3 四子棋编写代码
第 15章 面向对象编程和类
15.1 拿现实世界打比方:填写表格
15.2 基于类创建对象
15.3 创建一个简单的类——WizCoin
15.3.1 方法__init__()和self
15.3.2 特性
15.3.3 私有特性和私有方法
15.4 函数type()和特性__qualname__
15.5 非OOP 和OOP 的例子:井字棋
15.6 为现实世界设计类是一件难事儿
第 16章 面向对象编程和继承
16.1 继承的原理
16.1.1 重写方法
16.1.2 super()函数
16.1.3 倾向于组合而非继承
16.1.4 继承的缺点
16.2 函数isinstance()和issubclass()
16.3 类方法
16.4 类特性
16.5 静态方法
16.6 何时应该使用类和静态的面向对象特性
16.7 面向对象的行话
16.7.1 封装
16.7.2 多态性
16.8 何时不应该使用继承
16.9 多重继承
16.10 方法解析顺序
第 17章 Python 风格的面向对象编程:属性和魔术方法
17.1 属性
17.1.1 将特性转换为属性
17.1.2 使用setter 验证数据
17.1.3 只读属性
17.1.4 什么时候应该使用属性
17.2 Python 的魔术方法
17.2.1 字符串表示魔术方法
17.2.2 数值魔术方法
17.2.3 反射数值魔术方法
17.2.4 原地魔术方法
17.2.5 比较魔术方法
当前位置:
首页>>
技术小册>>
Python编程轻松进阶(五)
小册名称:Python编程轻松进阶(五)
### 17.1.3 只读属性 在Python编程中,只读属性是一种设计模式,它允许类的外部代码访问类的某些数据成员,但禁止直接修改这些数据成员。这种机制增强了类的封装性,使得类的内部状态更加安全可控,同时也提高了代码的可读性和可维护性。只读属性的实现方式多样,可以通过属性装饰器(property decorator)、私有变量加getter方法或使用描述符(descriptors)等方式来实现。本章节将深入探讨只读属性的概念、重要性以及几种常见的实现方法。 #### 17.1.3.1 只读属性的概念与重要性 **概念**: 只读属性,顾名思义,就是只能被读取而不能被修改的属性。在面向对象编程中,类的实例通常包含一些状态信息(即数据成员),这些信息在类的生命周期内可能会被外部代码访问以获取实例的当前状态,但有时我们不希望这些状态被外部随意修改,以保持对象状态的一致性和正确性。此时,就可以将这些数据成员封装为只读属性。 **重要性**: 1. **封装性**:只读属性是实现封装的重要手段之一,它隐藏了类的内部实现细节,只对外提供必要的接口,减少了外部代码对内部状态的直接依赖,降低了耦合度。 2. **数据保护**:通过限制对特定数据成员的修改,只读属性能够保护类的关键数据不被意外破坏,维护了对象状态的一致性和完整性。 3. **接口清晰**:只读属性提供了一种清晰的接口,让外部代码了解哪些数据是可以获取的,哪些是不可以修改的,有助于提升代码的可读性和易用性。 4. **安全性**:在敏感数据或系统关键配置的管理中,只读属性可以防止未授权的修改,提高系统的安全性。 #### 17.1.3.2 使用属性装饰器实现只读属性 Python的`@property`装饰器是实现只读属性的最简单直接的方式。通过它,我们可以将一个普通的方法转换为只读属性。在方法内部,我们可以执行任何必要的计算或逻辑判断,然后返回所需的值。由于这个方法被转换成了属性,所以外部代码在访问它时就像访问普通数据成员一样简单,但无法直接修改它。 ```python class Circle: def __init__(self, radius): self._radius = radius # 使用下划线前缀表示私有变量 @property def radius(self): """只读属性,返回圆的半径""" return self._radius @property def area(self): """只读属性,计算并返回圆的面积""" return 3.14 * self._radius ** 2 # 使用示例 circle = Circle(5) print(circle.radius) # 输出: 5 print(circle.area) # 输出: 78.5 # 尝试修改只读属性会失败 # circle.radius = 10 # 这将引发AttributeError ``` 在上述示例中,`_radius`是一个私有变量,它存储了圆的半径。通过`@property`装饰器,我们将`radius`和`area`方法转换成了只读属性。外部代码可以像访问普通属性一样读取它们的值,但无法直接修改它们(尝试修改`radius`会引发`AttributeError`)。 #### 17.1.3.3 私有变量加getter方法 除了使用`@property`装饰器外,另一种实现只读属性的方式是结合私有变量和getter方法。私有变量通过下划线前缀(一个或两个)来标识,表示它们仅能在类的内部被访问和修改。然后,我们为这些私有变量编写getter方法,这些方法可以执行任何必要的逻辑,并最终返回私有变量的值。虽然这种方式没有直接使用`@property`装饰器那么简洁,但它仍然是一种有效的实现只读属性的方法。 ```python class Rectangle: def __init__(self, width, height): self._width = width self._height = height def get_width(self): """返回矩形的宽度""" return self._width def get_height(self): """返回矩形的高度""" return self._height # 使用示例 rect = Rectangle(10, 20) print(rect.get_width()) # 输出: 10 print(rect.get_height()) # 输出: 20 # 尝试直接访问私有变量会失败(尽管在技术上可行,但不推荐这样做) # print(rect._width) # 这在技术上是可行的,但违反了封装原则 ``` #### 17.1.3.4 使用描述符实现高级只读属性 对于需要更复杂行为的只读属性,如动态计算、验证或依赖其他属性时,可以使用Python的描述符(descriptors)机制。描述符是实现了特定方法的对象,这些方法允许描述符控制对另一个对象的属性的访问。通过定义`__get__`、`__set__`和`__delete__`方法,我们可以完全控制属性的读取、修改和删除行为。对于只读属性,我们只需实现`__get__`方法,并在`__set__`和`__delete__`方法中抛出异常或执行其他必要的逻辑。 ```python class ReadOnlyDescriptor: def __init__(self, value): self.value = value def __get__(self, instance, owner): return self.value def __set__(self, instance, value): raise AttributeError("This attribute is read-only") def __delete__(self, instance): raise AttributeError("This attribute cannot be deleted") class User: name = ReadOnlyDescriptor("Unknown") # 使用示例 user = User() print(user.name) # 输出: Unknown # 尝试修改只读属性会失败 # user.name = "John Doe" # 这将引发AttributeError ``` 在上面的示例中,`ReadOnlyDescriptor`是一个描述符类,它实现了`__get__`、`__set__`和`__delete__`方法。对于只读属性,我们在`__set__`和`__delete__`方法中抛出了`AttributeError`异常,以阻止外部代码修改或删除该属性。然后,在`User`类中,我们将`name`属性设置为`ReadOnlyDescriptor`的一个实例,这样`User`类的实例就拥有了一个只读属性`name`。 #### 总结 只读属性是Python编程中一种重要的设计模式,它通过限制对类内部数据的直接修改来增强类的封装性和安全性。在Python中,我们可以通过多种方式实现只读属性,包括使用`@property`装饰器、私有变量加getter方法以及描述符等。每种方法都有其适用场景和优缺点,开发者应根据具体需求选择合适的方式来实现只读属性。通过合理使用只读属性,我们可以编写出更加健壮、易于维护和扩展的代码。
上一篇:
17.1.2 使用setter 验证数据
下一篇:
17.1.4 什么时候应该使用属性
该分类下的相关小册推荐:
Python爬虫入门与实战开发(下)
剑指Python(磨刀不误砍柴工)
Python自动化办公实战
Python合辑14-面向对象编程案例(下)
Python合辑5-格式化字符串
Python合辑1-Python语言基础
Python面试指南
机器学习算法原理与实战
Python与办公-玩转Word
Python高性能编程与实战
Python合辑2-字符串常用方法
Python机器学习实战