当前位置:首页>python>Python 双下划线方法完全指南

Python 双下划线方法完全指南

  • 2026-10-11 16:43:42
Python 双下划线方法完全指南

目录(双下划线方法分类)

  • 对象生命周期
  • 字符串表示
  • 属性访问
  • 容器与序列
  • 比较与哈希
  • 数值运算
  • 上下文管理
  • 异步编程
  • 类与元类
  • 序列化
  • 其他特殊方法

1. 对象生命周期类

1.1 创建与销毁

方法
触发时机
说明
__new__(cls, [,...])obj = MyClass()实例创建前
,返回新实例(类方法)
__init__(self, [,...])
刚创建后
初始化实例,无返回值
__del__(self)del obj
 或垃圾回收
析构函数,清理资源

示例:

classLifecycleDemo:def__new__(cls, *args, **kwargs):        print("1. __new__ 被调用")return super().__new__(cls)def__init__(self, name):        print("2. __init__ 被调用")        self.name = namedef__del__(self):        print(f"3. __del__ 被调用:{self.name} 被销毁")obj = LifecycleDemo("测试")del obj

1.2 单例模式

classSingleton:    _instance = Nonedef__new__(cls):if cls._instance isNone:            cls._instance = super().__new__(cls)return cls._instancedef__init__(self):# 注意:每次Singleton()都会执行__init__        print("初始化")# 验证a = Singleton()b = Singleton()print(a is b)  # True

2. 字符串表示类

2.1 基础表示

方法
触发时机
说明
__repr__(self)repr(obj)
、交互式环境
开发者友好,应能重建对象
__str__(self)str(obj)
、print(obj)
用户友好,可读性强
__format__(self, spec)format(obj)
、f-string
自定义格式化
__bytes__(self)bytes(obj)
返回字节表示

示例:

classPerson:def__init__(self, name, age):        self.name = name        self.age = agedef__repr__(self):returnf"Person('{self.name}', {self.age})"def__str__(self):returnf"{self.name} ({self.age}岁)"def__format__(self, spec):if spec == 'chinese':returnf"{self.name},{self.age}岁"return str(self)p = Person("张三", 25)print(repr(p))    # Person('张三', 25)print(str(p))     # 张三 (25岁)print(f"{p:chinese}")  # 张三,25岁

2.2 特殊显示

方法
触发时机
说明
__dir__(self)dir(obj)
自定义属性列表
__sizeof__(self)sys.getsizeof(obj)
对象内存大小

3. 属性访问类

3.1 基础访问协议

方法
触发时机
说明
__getattr__(self, name)
属性不存在时
处理缺失属性
__getattribute__(self, name)每次
属性访问
无条件调用,慎用
__setattr__(self, name, value)
设置属性
obj.x = value
__delattr__(self, name)
删除属性
del obj.x

示例:

classSmartObject:def__init__(self):        self._data = {}def__getattr__(self, name):"""当属性不存在时调用"""        print(f"获取缺失属性:{name}")return self._data.get(name, f"{name}不存在")def__setattr__(self, name, value):"""拦截所有属性设置"""if name.startswith('_'):# 私有属性直接设置            super().__setattr__(name, value)else:            print(f"设置属性:{name} = {value}")            self._data[name] = valuedef__delattr__(self, name):"""删除属性"""if name in self._data:del self._data[name]            print(f"删除属性:{name}")else:            super().__delattr__(name)obj = SmartObject()obj.name = "Python"# 设置属性print(obj.name)      # Pythonprint(obj.age)       # age不存在del obj.name         # 删除属性

3.2 描述符协议

方法
触发时机
说明
__get__(self, instance, owner)
访问描述符属性
instance
为None时访问类属性
__set__(self, instance, value)
设置描述符属性
数据描述符
__delete__(self, instance)
删除描述符属性
__set_name__(self, owner, name)
类创建时
3.6+,自动设置描述符名

示例:

classValidatedAttribute:"""验证属性的描述符"""def__init__(self, validator):        self.validator = validator        self.data = {}def__set_name__(self, owner, name):        self.private_name = f"_{name}"        print(f"描述符 {name} 绑定到 {owner.__name__}")def__get__(self, instance, owner):if instance isNone:return selfreturn self.data.get(instance, self.validator.default)def__set__(self, instance, value):ifnot self.validator(value):raise ValueError(f"无效值:{value}")        self.data[instance] = valuedef__delete__(self, instance):del self.data[instance]classPositiveNumber:"""验证正数的描述符"""def__init__(self, default=0):        self.default = defaultdef__call__(self, value):return isinstance(value, (int, float)) and value > 0classPerson:    age = ValidatedAttribute(PositiveNumber(18))    score = ValidatedAttribute(PositiveNumber(60))def__init__(self, name, age, score):        self.name = name        self.age = age      # 使用描述符        self.score = score  # 使用描述符p = Person("张三", 25, 85)print(p.age)   # 25# p.age = -5   # ValueError: 无效值:-5

3.3 内存优化

classPoint:    __slots__ = ['x', 'y']  # 限制属性,节省内存def__init__(self, x, y):        self.x = x        self.y = y

4. 容器与序列类

4.1 基础容器方法

方法
触发时机
说明
__len__(self)len(obj)
返回容器长度
__getitem__(self, key)obj[key]
获取元素
__setitem__(self, key, value)obj[key] = value
设置元素
__delitem__(self, key)del obj[key]
删除元素
__contains__(self, item)item in obj
成员测试

4.2 迭代相关

方法
触发时机
说明
__iter__(self)iter(obj)
、for循环
返回迭代器
__next__(self)next(iterator)
返回下一项
__reversed__(self)reversed(obj)
返回反向迭代器

示例:

classRange:"""自定义可迭代范围"""def__init__(self, start, end):        self.start = start        self.end = enddef__len__(self):return max(0, self.end - self.start)def__getitem__(self, index):if index < 0or index >= len(self):raise IndexError("索引超出范围")return self.start + indexdef__setitem__(self, index, value):# 只读容器,禁止设置raise TypeError("Range对象不支持赋值")def__contains__(self, item):return self.start <= item < self.enddef__iter__(self):        print("开始迭代")for i in range(self.start, self.end):yield idef__reversed__(self):        print("反向迭代")for i in range(self.end - 1, self.start - 1, -1):yield i# 使用r = Range(1, 5)print(len(r))          # 4print(r[2])            # 3print(3in r)          # Trueprint(list(r))         # [1, 2, 3, 4]print(list(reversed(r)))  # [4, 3, 2, 1]

4.3 序列运算

方法
触发时机
说明
__add__(self, other)obj + other
拼接
__mul__(self, n)obj * n
重复
__rmul__(self, n)n * obj
反向重复

5. 比较与哈希类

5.1 比较运算符

方法
运算符
说明
__eq__(self, other)==
相等
__ne__(self, other)!=
不等
__lt__(self, other)<
小于
__le__(self, other)<=
小于等于
__gt__(self, other)>
大于
__ge__(self, other)>=
大于等于

5.2 哈希与布尔

方法
触发时机
说明
__hash__(self)hash(obj)
用于字典键、集合
__bool__(self)bool(obj)
真值测试

示例:

classStudent:def__init__(self, name, score):        self.name = name        self.score = scoredef__eq__(self, other):ifnot isinstance(other, Student):returnFalsereturn self.name == other.namedef__lt__(self, other):return self.score < other.scoredef__hash__(self):return hash(self.name)def__bool__(self):return self.score >= 60# 是否及格def__repr__(self):returnf"Student({self.name}, {self.score})"# 测试students = [    Student("张三", 85),    Student("李四", 45),    Student("王五", 92)]print(sorted(students))  # 按分数排序print(bool(students[1]))  # False (不及格)print({s.name: s for s in students})  # 可哈希,可作字典键

5.3 简化比较

from functools import total_ordering@total_ordering  # 只需实现 __eq__ 和 一个比较方法classPerson:def__init__(self, name, age):        self.name = name        self.age = agedef__eq__(self, other):return self.age == other.agedef__lt__(self, other):return self.age < other.agedef__repr__(self):returnf"Person({self.name}, {self.age})"# 自动获得所有比较方法p1 = Person("A", 20)p2 = Person("B", 30)print(p1 <= p2)  # Trueprint(p1 != p2)  # True

6. 数值运算类

6.1 算术运算

类别
正向
反向
增量
说明
加法
__add____radd____iadd__+
减法
__sub____rsub____isub__-
乘法
__mul____rmul____imul__*
除法
__truediv____rtruediv____itruediv__/
整除
__floordiv____rfloordiv____ifloordiv__//
取模
__mod____rmod____imod__%
幂
__pow____rpow____ipow__**

6.2 位运算

运算
正向
反向
增量
说明
按位与
__and____rand____iand__&
按位或
__or____ror____ior__|
异或
__xor____rxor____ixor__^
左移
__lshift____rlshift____ilshift__<<
右移
__rshift____rrshift____irshift__>>
取反
__invert__
-
-
~

6.3 类型转换

方法
触发时机
说明
__int__(self)int(obj)
转为整数
__float__(self)float(obj)
转为浮点数
__complex__(self)complex(obj)
转为复数
__index__(self)
切片、bin()等
转为纯整数

示例:

classFraction:"""分数类"""def__init__(self, numerator, denominator=1):if denominator == 0:raise ValueError("分母不能为0")        self.numerator = numerator        self.denominator = denominatordef__repr__(self):returnf"Fraction({self.numerator}, {self.denominator})"def__str__(self):returnf"{self.numerator}/{self.denominator}"# 加法def__add__(self, other):if isinstance(other, Fraction):return Fraction(                self.numerator * other.denominator + other.numerator * self.denominator,                self.denominator * other.denominator            )elif isinstance(other, (int, float)):return self + Fraction(other)returnNotImplementeddef__radd__(self, other):return self + otherdef__iadd__(self, other):        result = self + other        self.numerator, self.denominator = result.numerator, result.denominatorreturn self# 乘法def__mul__(self, other):if isinstance(other, Fraction):return Fraction(                self.numerator * other.numerator,                self.denominator * other.denominator            )elif isinstance(other, (int, float)):return Fraction(self.numerator * other, self.denominator)returnNotImplemented# 比较def__eq__(self, other):if isinstance(other, Fraction):return (self.numerator * other.denominator ==                     other.numerator * self.denominator)returnFalse# 类型转换def__float__(self):return self.numerator / self.denominatordef__int__(self):return int(float(self))def__abs__(self):return Fraction(abs(self.numerator), abs(self.denominator))def__neg__(self):return Fraction(-self.numerator, self.denominator)# 使用f1 = Fraction(1, 2)f2 = Fraction(1, 3)print(f1 + f2)      # 5/6print(f1 + 1)       # 3/2print(1 + f1)       # 3/2 (使用__radd__)print(float(f1))    # 0.5print(abs(Fraction(-1, 2)))  # 1/2

7. 上下文管理类

7.1 同步上下文

方法
触发时机
说明
__enter__(self)with obj:
进入with块,返回值赋给as变量
__exit__(self, exc_type, exc_val, exc_tb)
离开with块
清理资源,处理异常

示例:

classManagedFile:"""自动管理文件资源"""def__init__(self, filename, mode='r'):        self.filename = filename        self.mode = mode        self.file = Nonedef__enter__(self):        print(f"打开文件:{self.filename}")        self.file = open(self.filename, self.mode)return self.filedef__exit__(self, exc_type, exc_val, exc_tb):if self.file:            print(f"关闭文件:{self.filename}")            self.file.close()# 处理异常if exc_type isnotNone:            print(f"发生异常:{exc_val}")# 返回True表示异常已处理,不传播# 返回False(默认)表示异常继续传播returnTrue# 抑制异常# 使用with ManagedFile('test.txt', 'w') as f:    f.write('Hello World')# 即使这里出错,文件也会关闭

7.2 上下文应用示例

import timeclassTimer:"""计时器上下文管理器"""def__enter__(self):        self.start = time.perf_counter()return selfdef__exit__(self, *args):        self.end = time.perf_counter()        self.elapsed = self.end - self.start        print(f"执行时间:{self.elapsed:.4f}秒")classTransaction:"""模拟事务"""def__init__(self, db):        self.db = dbdef__enter__(self):        print("开始事务")return selfdef__exit__(self, exc_type, exc_val, exc_tb):if exc_type isNone:            print("提交事务")# self.db.commit()else:            print("回滚事务")# self.db.rollback()returnFalse# 传播异常# 使用with Timer():# 测量代码块执行时间    sum(range(1000000))

7.3 contextlib 简化

from contextlib import contextmanager@contextmanagerdefmanaged_file(filename, mode='r'):"""使用生成器实现上下文管理器"""    print(f"打开文件:{filename}")    f = open(filename, mode)try:yield ffinally:        print(f"关闭文件:{filename}")        f.close()# 使用with managed_file('test.txt', 'w') as f:    f.write('Hello')

8. 异步编程类

8.1 异步迭代器

方法
触发时机
说明
__aiter__(self)aiter(obj)
返回异步迭代器
__anext__(self)anext(iterator)
返回awaitable下一项

8.2 异步上下文

方法
触发时机
说明
__aenter__(self)async with obj:
异步进入
__aexit__(self, ...)
异步退出
清理资源

8.3 可等待对象

方法
触发时机
说明
__await__(self)await obj
返回迭代器

示例:

import asyncioimport randomclassAsyncRange:"""异步范围迭代器"""def__init__(self, start, end, delay=0.1):        self.current = start        self.end = end        self.delay = delaydef__aiter__(self):return selfasyncdef__anext__(self):if self.current >= self.end:raise StopAsyncIterationawait asyncio.sleep(self.delay)  # 模拟IO操作        value = self.current        self.current += 1return valueclassAsyncResource:"""异步资源管理器"""asyncdef__aenter__(self):        print("异步获取资源...")await asyncio.sleep(0.5)        print("资源已获取")return selfasyncdef__aexit__(self, exc_type, exc_val, exc_tb):        print("异步释放资源...")await asyncio.sleep(0.5)        print("资源已释放")returnFalse# 不抑制异常asyncdefwork(self):return random.randint(1, 100)# 使用示例asyncdefmain():# 异步迭代asyncfor num in AsyncRange(1, 5, 0.2):        print(f"得到:{num}")# 异步上下文asyncwith AsyncResource() as res:        result = await res.work()        print(f"工作结果:{result}")# asyncio.run(main())

9. 类与元类

9.1 类创建

方法
触发时机
说明
__init_subclass__(cls, **kwargs)
创建子类时
3.6+,子类初始化钩子
__class_getitem__(cls, item)cls[item]
3.9+,泛型支持

示例:

classBasePlugin:"""插件基类"""    plugins = []def__init_subclass__(cls, **kwargs):        super().__init_subclass__(**kwargs)# 自动注册子类        BasePlugin.plugins.append(cls)        print(f"注册插件:{cls.__name__}")defrun(self):raise NotImplementedErrorclassPluginA(BasePlugin):defrun(self):        print("插件A运行")classPluginB(BasePlugin):defrun(self):        print("插件B运行")print(BasePlugin.plugins)  # [PluginA, PluginB]

9.2 类型检查

方法
触发时机
说明
__instancecheck__(self, instance)isinstance(obj, class)
自定义实例检查
__subclasscheck__(self, subclass)issubclass(sub, class)
自定义子类检查

9.3 元类方法

classMeta(type):"""元类示例"""def__new__(mcls, name, bases, namespace):        print(f"创建类:{name}")# 添加类属性        namespace['created_by'] = 'Meta'return super().__new__(mcls, name, bases, namespace)def__call__(cls, *args, **kwargs):        print(f"调用类:{cls.__name__}")return super().__call__(*args, **kwargs)classMyClass(metaclass=Meta):def__init__(self):        print("初始化实例")# 创建类时执行Meta.__new__obj = MyClass()  # 执行Meta.__call__print(obj.created_by)  # Meta

10. 序列化类

Pickle 协议

方法
触发时机
说明
__getstate__(self)pickle.dump(obj)
获取序列化状态
__setstate__(self, state)pickle.load(obj)
从状态恢复
__reduce__(self)pickle
 默认机制
自定义pickle
__reduce_ex__(self, protocol)
带协议版本
兼容不同版本

示例:

import pickleclassSecureObject:def__init__(self, name, password):        self.name = name        self._password = password  # 敏感数据def__getstate__(self):"""序列化时调用"""        state = self.__dict__.copy()# 移除敏感数据if'_password'in state:del state['_password']# 添加元数据        state['_pickle_version'] = 1return statedef__setstate__(self, state):"""反序列化时调用"""# 恢复数据        self.__dict__.update(state)# 处理旧版本if'_pickle_version'notin state:            self._password = None# 清理元数据if'_pickle_version'in self.__dict__:del self.__dict__['_pickle_version']def__repr__(self):returnf"SecureObject({self.name}, {self._password})"obj = SecureObject("admin", "123456")print(obj)  # SecureObject(admin, 123456)# 序列化data = pickle.dumps(obj)# 反序列化(密码丢失)new_obj = pickle.loads(data)print(new_obj)  # SecureObject(admin, None)

11. 其他特殊方法

11.1 可调用对象

classCounter:"""带状态的函数对象"""def__init__(self):        self.count = 0def__call__(self):        self.count += 1        print(f"第{self.count}次调用")return self.countcounter = Counter()counter()  # 第1次调用counter()  # 第2次调用print(callable(counter))  # True

11.2 索引与切片

classSparseArray:"""稀疏数组"""def__init__(self):        self._data = {}def__getitem__(self, key):if isinstance(key, slice):# 处理切片            start = key.start or0            stop = key.stop            step = key.step or1return [self._data.get(i, 0) for i in range(start, stop, step)]return self._data.get(key, 0)def__setitem__(self, key, value):if value == 0and key in self._data:del self._data[key]elif value != 0:            self._data[key] = valuearr = SparseArray()arr[10] = 42arr[5] = 7print(arr[10])  # 42print(arr[1:15:2])  # 切片访问

11.3 运算符重载示例

classVector:"""向量类 - 综合示例"""def__init__(self, *components):        self.components = list(components)def__len__(self):return len(self.components)def__getitem__(self, i):return self.components[i]def__setitem__(self, i, value):        self.components[i] = valuedef__repr__(self):returnf"Vector{tuple(self.components)}"def__add__(self, other):if isinstance(other, Vector):if len(self) != len(other):raise ValueError("维度不匹配")return Vector(*[a + b for a, b in zip(self, other)])elif isinstance(other, (int, float)):return Vector(*[x + other for x in self])returnNotImplementeddef__radd__(self, other):return self + otherdef__iadd__(self, other):# 原地加法        result = self + other        self.components = result.componentsreturn selfdef__sub__(self, other):if isinstance(other, Vector):return Vector(*[a - b for a, b in zip(self, other)])returnNotImplementeddef__mul__(self, scalar):if isinstance(scalar, (int, float)):return Vector(*[x * scalar for x in self])returnNotImplementeddef__rmul__(self, scalar):return self * scalardef__neg__(self):return Vector(*[-x for x in self])def__abs__(self):return sum(x**2for x in self) ** 0.5def__bool__(self):return any(x != 0for x in self)def__eq__(self, other):if isinstance(other, Vector):return self.components == other.componentsreturnFalsedef__hash__(self):return hash(tuple(self.components))# 使用v1 = Vector(1, 2, 3)v2 = Vector(4, 5, 6)print(v1 + v2)     # Vector(5, 7, 9)print(v1 + 10)     # Vector(11, 12, 13)print(10 + v1)     # Vector(11, 12, 13)v1 += v2print(v1)          # Vector(5, 7, 9)print(abs(Vector(3, 4)))  # 5.0

快速参考表

类别
核心方法
次要方法
生命周期__init__
, __new__, __del__
字符串__str__
, __repr__
__format__
, __bytes__
容器__len__
, __getitem__
__setitem__
, __delitem__, __contains__
迭代__iter__
, __next__
__reversed__
, __aiter__, __anext__
属性__getattr__
, __setattr__
__getattribute__
, __delattr__, __slots__
描述符__get__
, __set__
__delete__
, __set_name__
比较__eq__
, __lt__
__ne__
, __le__, __gt__, __ge__
数值__add__
, __sub__, __mul__
反向、增量、类型转换
上下文__enter__
, __exit__
__aenter__
, __aexit__
可调用__call__
序列化__getstate__
, __setstate__
__reduce__
, __reduce_ex__
类工具__init_subclass____class_getitem__
, __instancecheck__


作者简介:码上工坊,探索用编程为己赋能,定期分享编程知识和项目实战经验。持续学习、适应变化、记录点滴、复盘反思、成长进步。

重要提示:本文主要是记录自己的学习与实践过程,所提内容或者观点仅代表个人意见,只是我以为的,不代表完全正确,欢迎交流讨论。


最新文章

随机文章