一、引言:对象的"出生"与"消亡"
在现实世界中,万物都有生命周期: 出生 → 活动 → 消亡。
同样,在 Python 的面向对象世界中,对象(Object) 也有自己的"生命历程"。 当对象被创建时,系统会自动调用构造函数(Constructor) ; 当对象被销毁时,系统会调用析构函数(Destructor)。
这两个特殊方法帮助我们在对象创建和销毁的时刻执行必要的初始化或清理操作。
二、构造函数(__init__())
1. 定义与作用
构造函数用于在对象创建时自动执行,用于:
- 初始化对象的属性;
- 执行必要的准备操作。
定义格式如下:
python
class 类名:
def __init__(self, 参数列表):
初始化语句
当创建对象时:
python
对象名 = 类名(参数)
Python 会自动调用 __init__() 方法。
2. 基本示例
python
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
print("一个Person对象被创建了!")
p = Person("张三", 20)
print(p.name, p.age)
输出:
一个Person对象被创建了!
张三 20
__init__()相当于对象的"出生证明",为新生的对象设定状态。
3. 构造函数中的 self
self 代表当前对象本身,通过它可以访问或绑定实例属性。
python
class Dog:
def __init__(self, name):
self.name = name
def bark(self):
print(f"{self.name}:汪汪汪!")
dog = Dog("旺财")
dog.bark()
输出:
旺财:汪汪汪!
4. 默认构造函数
如果类中没有定义 __init__(),Python 会自动提供一个"默认构造函数",什么也不做。
python
class Empty:
pass
obj = Empty()
print("对象已创建!")
输出:
对象已创建!
当不需要初始化逻辑时,可以不定义构造函数。
5. 构造函数的参数默认值
可以给参数设置默认值,让对象创建更灵活:
python
class Student:
def __init__(self, name="未命名", grade="未知"):
self.name = name
self.grade = grade
s1 = Student()
s2 = Student("小明", "高一")
print(s1.name, s1.grade) # 未命名 未知
print(s2.name, s2.grade) # 小明 高一
6. 在构造函数中调用其他方法
构造函数不仅可以初始化属性,也可以在创建时执行行为。
python
class File:
def __init__(self, filename):
self.filename = filename
self.open_file()
def open_file(self):
print(f"文件 {self.filename} 已打开")
f = File("data.txt")
输出:
kotlin
文件 data.txt 已打开
三、析构函数(__del__())
1. 定义与作用
析构函数用于在对象被销毁前执行清理工作,例如:
- 关闭文件;
- 释放网络连接;
- 打印日志或调试信息。
定义格式:
python
class 类名:
def __del__(self):
清理操作
当对象的引用计数归零时,Python 会自动调用 __del__()。
2. 基本示例
python
class Person:
def __init__(self, name):
self.name = name
print(f"{self.name} 出生了")
def __del__(self):
print(f"{self.name} 离开了世界")
p1 = Person("张三")
p2 = Person("李四")
del p1 # 主动删除对象
print("程序执行完毕")
输出示例:
张三 出生了
李四 出生了
张三 离开了世界
程序执行完毕
李四 离开了世界
3. 析构函数的自动调用时机
Python 使用**垃圾回收机制(Garbage Collection)**来管理内存。 当对象不再被引用时(引用计数为0),__del__() 会被自动调用。
python
def test():
a = Person("王五")
test() # 函数执行完毕后,局部变量 a 被销毁
print("函数结束")
输出:
王五 出生了
王五 离开了世界
函数结束
4. 析构函数的注意事项
- 不要在析构函数中执行复杂逻辑,因为调用时机可能不确定;
- 对象间循环引用会延迟或阻止析构;
- Python 程序结束时会清理所有对象,但执行顺序不可预测。
四、构造与析构的协作------对象的生命周期
对象的完整生命周期:
-
创建阶段
- 调用
__init__()构造函数; - 初始化属性;
- 执行启动逻辑。
- 调用
-
使用阶段
- 对象参与运算、函数调用;
- 可能被多处引用。
-
销毁阶段
- 引用计数归零;
- 调用
__del__(); - 释放资源。
示例:
python
class Life:
def __init__(self, name):
self.name = name
print(f"{self.name} 诞生了")
def __del__(self):
print(f"{self.name} 消亡了")
a = Life("A")
b = Life("B")
a = None
print("执行中...")
b = None
输出:
css
A 诞生了
B 诞生了
A 消亡了
执行中...
B 消亡了
五、构造与析构在实际开发中的应用场景
1. 文件资源管理
python
class FileHandler:
def __init__(self, path):
self.file = open(path, "w", encoding="utf-8")
print("文件已打开")
def write(self, text):
self.file.write(text)
def __del__(self):
self.file.close()
print("文件已关闭")
f = FileHandler("test.txt")
f.write("Hello Python!")
当程序结束或对象被删除时,文件会自动关闭。
2. 数据库连接管理
python
class DBConnection:
def __init__(self):
print("数据库连接已建立")
def query(self):
print("执行SQL查询...")
def __del__(self):
print("数据库连接已关闭")
conn = DBConnection()
conn.query()
六、小结
| 函数 | 名称 | 调用时机 | 作用 |
|---|---|---|---|
__init__() |
构造函数 | 创建对象时 | 初始化对象属性 |
__del__() |
析构函数 | 对象销毁前 | 清理资源或关闭连接 |
提示:
- 构造函数几乎在每个类中都会使用;
- 析构函数适合管理文件、网络等有限资源;
- 如果使用
with语句或上下文管理器(Context Manager),推荐使用__enter__和__exit__替代析构函数。
七、结语
构造函数与析构函数,是 Python 对象生命周期中最重要的"开始"与"结束"。
__init__让对象诞生时充满灵魂,__del__让对象离开时井然有序。
理解这两者,意味着你真正掌握了对象的生命节奏。