Python 对象(或类)的特殊方法,通常被称为 魔术方法
🤖 Assistant
Python 对象(或类)的特殊方法,通常被称为 “魔术方法” (Magic Methods) 或 “双下划线方法” (Dunder Methods)。它们允许你重载操作符、自定义类的行为,并与 Python 的内置函数和语法进行交互。
下面我将逐一介绍这些方法的作用:
核心属性和方法
__class__
- 作用: 这个属性指向实例所属的类。
- 示例:
obj.__class__会返回type(obj)。 - 场景: 反射、类型检查。
__dict__
- 作用: 实例的属性字典。包含实例可变的状态(通过
self.attribute = value设置的属性)。并非所有对象都有__dict__,例如使用了__slots__的类实例。 - 示例:
obj.__dict__。 - 场景: 检查或动态修改实例属性、序列化/反序列化。
__module__
- 作用: 指向定义这个类或函数的模块的名称。
- 示例:
MyClass.__module__。 - 场景: 反射、调试、元编程。
__doc__
- 作用: 类的文档字符串。
- 示例:
MyClass.__doc__或help(MyClass)。 - 场景: 提供代码说明和帮助。
__weakref__
- 作用: 如果定义(默认有),这是实例的弱引用(weak reference)列表。
- 场景: 当对象需要被弱引用时,例如缓存系统或循环引用管理。
__slots__可以阻止创建__weakref__。
构造与初始化方法
__new__(cls, *args, **kwargs)
- 作用: 类的创建方法。它在
__init__之前被调用,负责创建并返回一个新实例。它是一个classmethod,第一个参数是类本身cls。很少需要重写,除非你想要创建不可变对象或实现单例模式。 - 返回值: 必须返回新创建的实例 (通常通过
super().__new__(cls, ...))。 - 场景: 单例模式、不可变类的定制、元编程。
__init__(self, *args, **kwargs)
- 作用: 类的初始化方法。它在
__new__创建实例后被调用,负责初始化实例的属性。它是一个实例方法。 - 返回值: 无返回值 (隐式返回
None)。 - 场景: 设置实例的初始状态和属性。
__init_subclass__(cls)
- 作用: 类被继承时,在子类创建后自动调用。它是一个
classmethod,接收新创建的子类cls作为参数。 - 场景: 元类(
metaclass) 的轻量级替代,用于在子类定义时对其进行注册、验证或修改。
属性访问控制方法
__getattribute__(self, name)
- 作用: 在每次访问实例的属性时(
obj.attr)无条件被调用。如果你在这里犯错,可能会导致无限递归(例如,在__getattribute__内部又访问了self.name)。 - 场景: 实现代理对象、日志记录属性访问、阻止某些属性被访问。
- 注意: 这是一个非常强大的方法,慎用。通常更倾向于使用
__getattr__。
__getattr__(self, name)
- 作用: 仅当尝试访问的属性
name不存在于实例的__dict__或其类及基类中时才会被调用。 - 场景: 实现动态属性、代理未知属性、处理拼写错误的属性。
__setattr__(self, name, value)
- 作用: 在每次设置实例属性时(
obj.attr = value)无条件被调用。 - 场景: 属性验证、日志记录属性修改、只读属性实现。
- 注意: 内部设置属性时必须调用
object.__setattr__(self, name, value)以避免无限递归。
__delattr__(self, name)
- 作用: 在每次删除实例属性时(
del obj.attr)无条件被调用。 - 场景: 清理资源、日志记录属性删除。
- 注意: 内部删除属性时必须调用
object.__delattr__(self, name)以避免无限递归。
表达与表示方法
__repr__(self)
- 作用: 返回对象的“官方”字符串表示,目标是明确且不含糊,通常用于调试和开发。理想情况下,它应该返回一个可以用于重新创建对象的字符串(如果可能)。
- 示例:
repr(obj)或直接在交互式解释器中输入obj。 - 场景: 调试、日志记录。
__str__(self)
- 作用: 返回对象的“非正式”字符串表示,目标是可读性强,供普通用户阅读。
- 示例:
str(obj)或print(obj)。 - 场景: 用户友好的输出、日志记录。
比较操作方法
(这些方法都接受 self 和 other 作为参数,返回布尔值 True 或 False)
__eq__(self, other)
- 作用: 定义相等操作符 (
==) 的行为。 - 场景: 比较两个对象是否相等。
__ne__(self, other)
- 作用: 定义不相等操作符 (
!=) 的行为。通常,如果定义了__eq__,Python 会默认提供__ne__的反向逻辑。 - 场景: 比较两个对象是否不相等。
__lt__(self, other)
- 作用: 定义小于操作符 (
<) 的行为。 - 场景: 排序、比较大小。
__le__(self, other)
- 作用: 定义小于等于操作符 (
<=) 的行为。 - 场景: 排序、比较大小。
__gt__(self, other)
- 作用: 定义大于操作符 (
>) 的行为。 - 场景: 排序、比较大小。
__ge__(self, other)
- 作用: 定义大于等于操作符 (
>=) 的行为。 - 场景: 排序、比较大小。
__hash__(self)
- 作用: 返回对象的哈希值。如果一个对象要被用作字典的键或集合的元素,它必须是可哈希的。通常如果重写了
__eq__,也应该重写__hash__。可变对象通常不可哈希。 - 场景: 使用对象作为
dict键或set元素。
类型与运行时信息方法
__dir__(self)
- 作用: 返回对象可用的属性和方法列表。
dir(obj)函数会调用它。 - 场景: 自定义
dir()函数的行为,例如在代理对象中显示其代理的属性。
__format__(self, format_spec)
- 作用: 定义当对象使用
format()函数或格式化字符串字面量 (f-string) 进行格式化时的行为。 - 场景: 自定义对象的格式化输出。
__sizeof__(self)
- 作用: 返回对象在内存中占用的字节数。
sys.getsizeof(obj)函数会调用它。 - 场景: 内存分析。
__subclasshook__(cls, C)
- 作用: 这是一个类方法,用于实现抽象基类 (ABC) 的自定义子类检查逻辑。它允许一个类在不显式继承另一个类的情况下,被认为(作为虚拟子类)是它的子类。
- 场景: 实现鸭子类型 (Duck Typing) 的抽象基类,例如
collections.abc模块中的类。
序列化和拷贝方法
__reduce__(self)和__reduce_ex__(self, protocol)
- 作用: 这两个方法在对象进行序列化(例如使用
pickle模块)时被调用。它们返回一个字符串或一个元组,描述如何重新构造这个对象。 __reduce_ex__允许指定协议版本。- 场景: 自定义对象的
pickle行为,特别是当对象不能直接通过__init__重新创建时。
理解它们对于编写健壮、可维护和行为可控的 Python 代码至关重要。
浙公网安备 33010602011771号