Python面向对象内置方法详解:__str__、__del__与__call__
本文深入解析Python面向对象编程中的三个核心内置方法:__str__、__del__和__call__。详细讲解__str__在对象打印时的触发机制与属性查找顺序,__del__在垃圾回收前的执行逻辑,以及__call__如何控制对象与类的调用行为。通过元类自定义__call__方法的示例,揭示类实例化的完整底层流程,帮助开发者掌握Python对象模型的关键细节。
在Python的class类定义中,存在一系列内置方法,例如__call__和__str__等。这些特殊方法在满足特定条件时会自动触发运行,无需手动调用。
接下来将详细介绍几个常用的内置方法及其工作原理。
1、__str__
首先说明其作用:当使用print函数打印对象实例时,会自动触发并运行该方法。
示例1如下:
class Student:
def __init__(self,name,age):
self.name = name
self.age = age
stu1 = Student('xiaoming',18)
print(stu1) #运行原理就是,先在Student类里找__str__方法,没有就去他的父类找
print(object.__str__(stu1)) #验证了Student的父类里面有__str__方法
其输出结果为:
#<__main__.Student object at 0x0000023A1170C128> #<__main__.Student object at 0x0000023A1170C128>
示例2:
我们可以在Student类中自定义一个__str__方法来进行验证。执行print打印操作时,其原理是调用了__str__方法。
class Student:
def __init__(self,name,age):
self.name = name
self.age = age
def __str__(self):
print(self.name)
return '<name:%s age:%s>' %(self.name,self.age)
stu1 = Student('xiaoming',18)
print(stu1) #这个stu1就是__str__的返回值输入结果为:
xiaoming <name:xiaoming age:18>
补充说明对象属性查找的顺序:首先查找对象自身的名称空间,若未找到则查找对象对应类的名称空间,最后查找该类的基类的名称空间。
2、__del__方法
该方法的作用是:在删除对象之前自动触发执行。
直接通过代码示例展示:
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
def __del__(self):
print('%s 已经被删除' % self.name)
stu1 = Student('xiaoming', 18)
stu2 = Student('zhangsan', 18)
print('主')其执行结果为:
主 xiaoming 已经被删除 zhangsan 已经被删除
解释为何输出上述结果:这涉及Python解释器的垃圾回收机制。当一个程序运行完毕,Python会回收该程序在内存中产生的数据。当执行到print('主')且后续没有代码执行时,解释器会删除stu1和stu2这两个对象。在删除这两个对象之前,会执行__del__方法,因此出现了上述输出结果。
3、__call__
在调用该对象时(即实例化过程中),会自动运行其类及类的基类中的__call__方法。如果该类中不存在此方法,则该对象是不可调用的。
class Student: #补充:class Student: 相当于就是 Student = type(类名,该类的基类们,类体代码产生的名称空间)
pass
Student()分析如下:一切皆对象,Student本身也是一个对象,它是通过元类type实例化得来的。因此,调用Student()时,实际上是去type元类中查找__call__方法并执行。由于type类中确实包含__call__方法,所以上述代码运行不会出错。
下面通过一个例子来验证上述结论:
class Student: # (相当于上面例子的type)
def __init__(self, name, age):
self.name = name
self.age = age
stu1 = Student('xiaoming', 18) # stu1(相当于上面例子的Student)
try: # 这里我们通过捕捉异常来打印出错原因
stu1() # 这里相当于上面Student()
except Exception as e:
print(e)
# 打印结果是:'Student' object is not callable
# “Student”对象不可调用,也就是stu1是不可调用的结论:通过这两个例子可以得出,只要该对象的类中包含__call__方法,那么该对象就可以被调用,即可以实例化。
该对象实例化的过程,本质上就是运行其类中的__call__方法。
进行验证:该对象实例化,即是运行其类中的__call__方法。
class Teacher:
def __init__(self, name):
self.name = name
def __call__(self, *args, **kwargs):
print('我被%s调用了' % self.name)
tea1 = Teacher('xiaoming')
tea1()
#输出结果是:我被xiaoming调用了
如何通过元类来控制类的调用?
可以通过在自定义元类中定义__call__方法,来实现对类的调用控制。
1、首先,类的调用原理就是运行元类中的__call__方法。
2、通过__call__方法来实现对对象的初始化操作。
class Mymeta(type):
def __call__(self, *args, **kwargs): # self就是Student *args和**kwargs就是Student后面的参数
# print(self)
# print(args)
# print(kwargs)
obj = self.__new__(self) # 就是创建一个Student的空对象
self.__init__(obj, *args, **kwargs) # 执行__init__方法 这里需要注意查找顺序
return obj # 将实例化完的对象返回回去
class Student(object, metaclass=Mymeta):
def __init__(self, name, age):
self.name = name
self.age = age
stu1 = Student('xiaoming', age=18)
print(type(stu1),stu1.__dict__)这就是类的实例化的整个过程。不过,这是通过自定义元类来控制类的调用,本质上只是在__call__中多写了一些代码而已。
在默认元类type中,必然存在__call__方法。该方法执行时,首先创建一个空对象,随后执行__init__方法。
目前先讲解这三个方法,其他如__dict__、__class__、__name__等属性不再赘述。
到此,这篇关于Python面向对象内置方法梳理讲解的文章就介绍到这了。更多相关Python面向对象内容请搜索本站以前的文章或继续浏览下面的相关文章,希望大家以后多多支持本站!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













