__init__ 方法必须带 self 参数且返回 None,它是初始化方法而非构造函数;不可返回值、避免可变默认参数、继承时需显式调用父类 __init__,且不宜做耗时或易失败操作。

__init__ 方法必须带 self 参数,且不能返回值
Python 的 __init__ 不是构造函数,而是初始化方法——对象已经创建完毕后才被调用。所以它没有返回值(也不能写 return 语句),否则会触发 TypeError: __init__() should return None 错误。
常见错误:误把它当 C++/Java 构造器,试图返回新实例或提前退出:
def __init__(self, name):
if not name:
return # ❌ 错误!这会让 self 初始化不完整,后续调用可能出 AttributeError
self.name = name-
self是强制第一个参数,代表当前实例,不可省略或改名(哪怕叫me也行,但不推荐) - 所有想绑定到实例上的属性,都必须显式赋值给
self.xxx,否则只是局部变量 - 如果不需要初始化逻辑,也得写
def __init__(self): pass,不能直接删掉
带默认参数时避免可变对象作默认值
这是最常踩的坑:用 [] 或 {} 当默认参数,会导致多个实例共享同一份内存。
class Cache:
def __init__(self, data=[]): # ❌ 危险!
self.data = data第一次调用 Cache().data.append(1) 后,下次再新建 Cache(),data 里已有 [1]。
立即学习“Python免费学习笔记(深入)”;
- 正确写法是用
None作默认值,再在方法内初始化:def __init__(self, data=None): self.data = data if data is not None else [] - 同理适用于
dict、set等可变类型 - 不可变类型如
int、str、tuple没这个问题
继承中必须显式调用父类 __init__
子类重写 __init__ 时,Python 不会自动调用父类的 __init__,必须手动用 super().__init__()。
class Animal:
def __init__(self, name):
self.name = name
<p>class Dog(Animal):
def <strong>init</strong>(self, name, breed):
super().<strong>init</strong>(name) # ✅ 必须加这一行
self.breed = breed- 漏掉
super().__init__()会导致父类字段(如self.name)未定义 - 如果父类
__init__有必需参数,不传会直接报TypeError - 多继承时,
super()按 MRO 顺序调用,比硬写Parent.__init__(self, ...)更安全
__init__ 中不适合做耗时或可能失败的操作
比如网络请求、文件读写、数据库连接——这些操作一旦失败,__init__ 抛异常,对象其实已经创建成功(__new__ 已执行),但处于半初始化状态,容易引发资源泄漏或难以 debug。
- 建议把这类逻辑拆到单独方法(如
load_config()、connect()),由用户显式调用 - 如果真要强制初始化,考虑用工厂函数或
@classmethod替代,例如cls.from_url(...) - 异常处理也更清晰:在
__init__里捕获并吞掉异常,会掩盖问题;而在独立方法里抛出,调用方能明确感知
真正难的是权衡:既要保证实例可用,又不能让 __init__ 变成“黑盒入口”。多数时候,轻量初始化 + 显式 setup 才是更可控的选择。


















