news 2026/6/15 10:05:51

Python 高手编程系列三千四百二十六:最佳实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python 高手编程系列三千四百二十六:最佳实践

为了避免前面提到的所有问题,在 Python 在这个领域取得进展之前,我们需要考虑以
下几点。
• 应该避免多重继承:可以采用第 14 章介绍的一些设计模式来代替它。
• super 的使用必须一致:在类的层次结构中,要么全部用 super,要么全不用。
混用 super 和传统调用是一种混乱的做法。人们往往会避免使用 super,这样代
码会更清晰。
• 如果代码的使用范围包括 Python 2,在 Python 3 中也应该显式地继承自 object:
在 Python 2 中,没有指定任何祖先的类被认为是旧式类。在 Python 2 中应避免混
用旧式类和新式类。
• 调用父类时必须查看类的层次结构:为了避免出现任何问题,每次调用父类时,必
须快速查看有关的 MRO(使用__mro__)。
高级属性访问模式
许多 C++和 Java 程序员第一次学习 Python 时,他们会对 Python 没有 private 关键
字感到惊讶。与之最接近的概念是名称修饰(name mangling)。每当在一个属性前面加上
__前缀,解释器就会立刻将其重命名:
class MyClass:
__secret_value = 1
利用原始名称访问__secret_value 属性,将会引发 AttributeError 异常:

instance_of = MyClass()
instance
_of. _secret_value
Traceback (most recent call last):
File “”, line 1, in
AttributeError: ‘MyClass’ object has no attribute ’ _secretvalue’
dir(MyClass)
[’
_MyClass _secret_value’, ’ __class __‘, ’ __delattr __’, ’ __dict __‘, ’ __
dir __’, ’ __doc __‘, ’ __eq __’, ’ __format __‘, ’ __ge __’, ’ __getattribute __‘,
’ __gt __’, ’ __hash __‘, ’ __init __’, ’ __le __‘, ’ __lt __’, ’ __module __‘,
’ __ne __’, ’ __new __‘, ’ __reduce __’, ’ _reduce_ex __‘, ’ __repr __’, ’ __
setattr __‘, ’ __sizeof', ’str', ’subclasshook', ’weakref']
instance
of.MyClasssecretvalue
1
Python 提供这一特性是为了避免继承中的名称冲突,因为属性被重命名为以类名为前
缀的名称。这并不是真正的锁定(real lock),因为可以通过其组合名称来访问该属性。这
一特性可用于保护某些属性的访问,但在实践中,永远不应使用
。如果一个属性不是公
有的,约定使用_前缀。这不会调用任何名称修饰的算法,而只是说明这个属性是该类的私
有元素,这是流行的写法。
Python 中还有其他可用的机制来构建类的公有部分和私有代码。应该使用描述符和
property 这些 OOP 设计的关键特性来设计一个清晰的 API。
描述符
描述符(descriptor)允许你自定义在引用一个对象的属性时应该完成的事情。
描述符是 Python 中复杂属性访问的基础。它在内部被用于实现 property、方法、类
方法、静态方法和 super 类型。它是一个类,定义了另一个类的属性的访问方式。换句话
说,一个类可以将属性管理委托给另一个类。
描述符类基于 3 个特殊方法,这 3 个方法组成了描述符协议(descriptor protocol):
set(self, obj, type=None):在设置属性时将调用这一方法。在下面的
示例中,我们将其称为 setter。
get(self, obj, value):在读取属性时将调用这一方法(被称为 getter)。
delete(self, obj):对属性调用 del 时将调用这一方法。
实现了__get
()和__set
()的描述符被称为数据描述符(data descriptor)。如果只
实现了__get
(),那么就被称为非数据描述符(non-data descriptor)。
在每次属性查找中,这个协议的方法实际上由对象的特殊方法__getattribute
()
调用(不要与__getattr
()弄混,后者用于其他目的)。每次通过点号(形式为
instance.attribute)或者 getattr(instance, ‘attribute’)函数调用来执行
这样的查找时,都会隐式地调用__getattribute
(),它按下列顺序查找该属性:
1.验证该属性是否为实例的类对象的数据描述符。
2.如果不是,就查看该属性是否能在实例对象的__dict__中找到。
3.最后,查看该属性是否为实例的类对象的非数据描述符。
换句话说,数据描述符优先于__dict__查找,而__dict__查找优先于非数据描述符。
为了表达得更清楚,下面是 Python 官方文档中的示例,给出了描述符在真实代码中的
工作方式:
class RevealAccess(object):
“”“一个数据描述符,正常设定值并返回值,同时打印出记录访问的信息。
“””
definit(self, initval=None, name=‘var’):
self.val = initval
self.name = name
defget(self, obj, objtype):
print(‘Retrieving’, self.name)
return self.val
defset(self, obj, val):
print(‘Updating’, self.name)
self.val = val
class MyClass(object):
x = RevealAccess(10, ‘var “x”’)
y = 5
下面是在交互式会话中的使用示例:
m = MyClass()
m.x
Retrieving var “x”
10
m.x = 20
Updating var “x”
m.x
Retrieving var “x”
20
m.y
5
前一个例子清楚地表明,如果一个类的某个属性有数据描述符,那么每次查找这个属
性时,都会调用描述符的__get
()方法并返回它的值,每次对这个属性赋值时都会调用
set()。虽然前一个例子没有给出描述符__del__方法的例子,但现在也应该清楚了:
每次通过 del instance.attribute 语句或 delattr(instance, ‘attribute’)
调用删除一个实例属性时都会调用它。
由于上述原因,数据描述符和非数据描述符的区别很重要。Python 已经使用描述符协
议将类函数绑定为实例方法。它还支持了 classmethod 和 staticmethod 装饰器背后
的机制。事实上,这是因为函数对象也是非数据描述符,如下所示:
def function(): pass
hasattr(function, ’ __get __’)
True
hasattr(function, ’ __set __‘)
False
对于 lambda 表达式创建的函数也是如此:
hasattr(lambda: None, ’ __get __’)
True
hasattr(lambda: None, ’ __set __')
False
因此,如果没有__dict__优先于非数据描述符,我们将不可能在运行时在已经构建好
的实例上动态覆写特定的方法。幸运的是,多亏了 Python 描述符的工作方式。由于这一工
作方法,使得开发人员可以使用一种叫作猴子补丁(monkey-patching)的流行技术来改变
实例的工作方式,而不需要子类化。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/15 10:00:25

【Claude Code】Unable to resize image 报错:自动图片调整失败的诊断与手动修复

文章目录 一、问题描述 1.1 环境信息 1.2 报错现象 二、根因分析 2.1 错误链路追踪 2.2 可能原因列举 三、解决方案 方案一:格式转换(针对变体 A)(推荐) 方案二:手动缩放到安全尺寸 方案三:同时压缩文件大小 方案四:使用在线工具或 GUI 工具 四、验证与回归测试 五、总…

作者头像 李华
网站建设 2026/6/15 9:58:57

为什么你的 AI Agent Harness Engineering 工具调用成功率低?6个优化技巧实测

为什么你的AI Agent Harness Engineering工具调用成功率低?6个优化技巧实测有效 副标题:附LangChain/Pydantic实现代码,成功率从37%提升到94%的可落地方案 第一部分:引言与基础 1.1 摘要/引言 你有没有遇到过这种场景:花了一周时间搭好了AI Agent的逻辑框架,接入了天气…

作者头像 李华
网站建设 2026/6/15 9:57:53

【Linux企业级应用】LVS+Keepalived高可用001篇

文章目录 LVS + Keepalived 双机热备(DR模式高可用)完整实战 一、整体架构与思路 核心要点 二、IP规划示例 三、安装软件 两台Director(master & backup)上都装 Real Server上只需要标准网络工具(不用装LVS) 四、关键网络配置 1️⃣ Director 端 —— VIP不需要手动绑…

作者头像 李华