Python类对象的构造与析构机制及内存释放演示
本文详细解析Python中类对象的构造函数[[wp:a0]]与析构函数[[wp:a1]]的工作机制,并通过代码演示对象创建、引用更迭、函数内部生命周期及返回值处理时的内存分配与释放过程,帮助开发者深入理解Python对象的内存管理。
一、类的构造函数与析构函数
- 在Python类中,
_init__是类的构造函数,当创建一个类实例时,系统会自动调用该函数。它的主要作用是在对象初始化阶段设置必要的初始信息和配置。 __del__则是类的析构函数,当一个类实例的生命周期结束、即将被销毁时,系统会自动调用此函数。其核心用途是释放对象所占用的资源,如文件句柄、网络连接等。
二、代码演示
1. 引用的更迭
以下代码展示了一个名为demo的类的基本实现。
>>> class demo():
... def __init__(self):
... print("init class")
... print(self)
... def __del__(self):
... print("del class")
... print(self)
...
>>> 当创建该类实例时,系统会调用__init__函数,输出“init class”;当实例被销毁时,系统会调用__del__函数,输出“del class”。
>>> a1 = demo()
init class
<__main__.demo instance at 0x7f328f7c6cb0>
>>>
>>> a2 = demo()
init class
<__main__.demo instance at 0x7f328f7c6d40>
>>>
>>>
>>>
>>> a1 = demo()
init class
<__main__.demo instance at 0x7f328f7c6d88>
del class
<__main__.demo instance at 0x7f328f7c6cb0>
>>> 首先,使用变量a1引用一个demo类实例,此时控制台打印“init class”以及a1所指向的对象内存地址0x7f328f7c6cb0。
接着,使用变量a2引用另一个独立的demo类实例,此时控制台再次打印“init class”以及a2所指向的对象内存地址0x7f328f7c6d40。
此时,a1和a2分别指向两个不同的对象实例,其内存地址分别为0x7f328f7c6cb0和0x7f328f7c6d40。
最后,再次创建一个新的demo类实例,并让a1重新指向这个新对象,此时a1引用的新对象地址为0x7f328f7c6d88。由于之前的旧对象0x7f328f7c6cb0不再被任何变量引用,其引用计数归零,Python解释器自动回收该对象空间,并触发析构函数,打印出“del class 0x7f328f7c6cb0”。
2. 只在函数内部的类对象
>>> def create_demo():
... inst = demo()
...
>>> create_demo()
init class
<__main__.demo instance at 0x7f328f7c6cb0>
del class
<__main__.demo instance at 0x7f328f7c6cb0>
>>>
>>>
>>>
>>> create_demo()
init class
<__main__.demo instance at 0x7f328f7c6cb0>
del class
<__main__.demo instance at 0x7f328f7c6cb0>
>>>
>>>
>>>
>>> create_demo()
init class
<__main__.demo instance at 0x7f328f7c6cb0>
del class
<__main__.demo instance at 0x7f328f7c6cb0>
>>> 定义一个名为create_demo的函数,该函数内部创建demo类实例,并使用局部变量inst进行引用。
调用一次create_demo()函数,可以看到demo对象被成功创建,其内存地址为0x7f328f7c6cb0;然而,由于该对象仅在函数局部作用域内有效,函数执行完毕后,局部变量inst被销毁,导致demo对象失去所有引用,随即被垃圾回收机制释放。
再次调用create_demo()函数,现象一致:demo对象被创建,地址为0x7f328f7c6cb0;函数结束后,该对象立即被释放。
三、函数内部返回的类对象
>>> def return_demo():
... return demo()
... 定义函数return_demo,该函数内部创建demo类实例,并通过return语句返回该实例。
>>> True
True
>>> return_demo()
init class
<__main__.demo instance at 0x7fc511eb8cb0>
<__main__.demo instance at 0x7fc511eb8cb0>
>>>
>>> True
del class
<__main__.demo instance at 0x7fc511eb8cb0>
True
>>>
>>> return_demo()
init class
<__main__.demo instance at 0x7fc511eb8cb0>
<__main__.demo instance at 0x7fc511eb8cb0>
>>>
>>>
>>>
>>> True
del class
<__main__.demo instance at 0x7fc511eb8cb0>
True
>>>
>>> 第一次调用return_demo()函数时,控制台显示创建了一个对象,其内存地址为0x7fc511eb8cb0;函数内部使用return语句返回该实例,因此函数返回时,对象0x7fc511eb8cb0并未被立即释放,而是被返回给调用者。
随后,执行一条Python语句:True。此时观察到对象0x7fc511eb8cb0被释放。这是因为在调用return_demo()后,如果后续代码没有对该返回值进行引用(例如未赋值给变量),Python解释器会认为该对象不再被使用,从而自动释放其占用的内存空间0x7fc511eb8cb0。
第二次执行相同的操作,观察到的现象与第一次基本相同。
>>> v1_demo = None
>>> v2_demo = None
>>> print(v1_demo)
None
>>> print(v2_demo)
None
>>> True
True
>>>
>>> v1_demo = return_demo()
init class
<__main__.demo instance at 0x7fc511eb8d88>
>>>
>>> print(v1_demo)
<__main__.demo instance at 0x7fc511eb8d88>
>>>
>>> True
True
>>>
>>>
>>> v2_demo = return_demo()
init class
<__main__.demo instance at 0x7fc511eb8dd0>
>>>
>>> print(v2_demo)
<__main__.demo instance at 0x7fc511eb8dd0>
>>> True
True
>>>
>>>
>>>
>>>
>>> v1_demo = None
del class
<__main__.demo instance at 0x7fc511eb8d88>
>>>
>>> print(v1_demo)
None
>>> 该代码段的行为与前一个代码段类似,主要区别在于对象的生命周期由返回值的引用情况决定。
可以看到,当v1_demo和v2_demo分别引用了return_demo()返回的类对象后,它们的值不再是None,而是指向具体的实例地址。
最后,我们将v1_demo重新赋值为None。此时,v1_demo之前引用的对象0x7fc511eb8d88因失去引用而被释放。
1. 使用全局变量引用函数内部的类对象
>>> g_demo = None
>>> print(g_demo)
None
>>>
>>> def return_gdemo():
... global g_demo
... g_demo = demo()
...
>>>
>>> print(g_demo)
None
>>> return_gdemo()
init class
<__main__.demo instance at 0x7fc511eb8d88>
>>>
>>> print(g_demo)
<__main__.demo instance at 0x7fc511eb8d88>
>>>
>>> True
True
>>> 到此,关于Python类对象构造与析构及内存释放的演示介绍完毕。更多Python类对象相关知识,请查阅本站往期文章或继续浏览后续内容,感谢支持!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









