Wu_Candy

V1

2022/07/26阅读:12主题:默认主题

Python 5大常用魔术方法汇总

前言

Python 中,以双下划线__包起来的方法,统称为:魔术方法(Magic Method)

魔术方法是一个类或对象中的特殊方法,和普通方法的区别在于,普通方法需要手动调用,而魔术方法是在特定时刻自动触发执行的

如果希望根据自己的程序定制自己特殊功能的类,那么就需要对这些魔术方法进行重写

五个常用魔术方法

1. __new__

(1). 说明:实例化对象方法

(2). 触发时机:在实例化时触发

(3). 参数:至少得有一个cls接收当前类,写法为__new__(cls, *args, **kwargs)

(4). 返回值:必须使用return关键字返回一个对象实例

(5). 作用:实例化(创建)对象,开辟内存地址空间对象并返回

(6). 注意:实例化对象是Object类底层实现,其他类继承了Object__new__才能够实现实例化对象

2. __init__

(1). 说明:初始化方法,相当于java中的构造方法,在__new__执行后被调用

(2). 触发时机:初始化对象时触发(区别于__new__实例化时的触发)

(3). 参数:至少得有一个self接收__new__方法返回的对象,写法为__init__(self, name, age)

(4). 返回值:无

(5). 作用:初始化对象的成员

(6). 注意:使用该方式初始化的成员都是直接写入对象当中,类中无法具有

3. __del__

(1). 说明:析构魔术方法

(2). 触发时机:当一块地址空间没有任何指针引用的时候被触发

  • 在 Python 解释器中,当所有代码程序执行完成则会进行垃圾回收,也叫内存释放,这时就会触发__del__方法

  • 使用del 对象名显示删除引用关系时,如果此操作将某块地址空间的最后一个引用关系给删除,则会触发__del__方法

(3). 参数:仅只一个self参数接收对象

(4). 返回值:无

(5). 作用:使用完对象时回收资源,没有指针引用的时候会调用,绝大多数时候不需要重写

(6). 注意:del 对象名不一定会触发当前方法,只有某块地址空间无任何引用时才会触发

4. __call__

(1). 说明:调用对象函数的魔术方法

(2). 触发时机:将对象当作函数调用时触发,使用形式为对象名称(),会默认调用__call__函数里的内容

(3). 参数:至少得有一个self接收对象,剩余参数根据调用时传入的参数决定,写法为__call__(self, args)

(4). 返回值:根据具体重写逻辑而定

(5). 作用:将复杂的步骤统一放在该函数内实现,减少调用的步骤,比较方便

(6). 注意:无

5. __str__

(1). 说明:当print(对象名)时想看到更多的信息时,可以重写__str__方法,将想要输出的信息放在__str__函数中返回

(2). 触发时机:使用print(对象名)或者str(对象名)的时候触发

(3). 参数:一个self参数接收对象

(4). 返回值:必须是字符串类型

(5). 作用:print(对象名)时可以自定义输出更多有用信息

(6). 注意:无

Python 代码

1. 代码实例
class People:  # 类名Person后面加不加(Object)效果是一样的,都表示继承自Object类
    # 创建对象
    def __new__(cls, *args, **kwargs):
        print("调用__new__构造方法")
        position = super().__new__(cls)  # 调用父类的__new__()方法创建对象,开辟内存空间
        # print(position)  # <__main__.People object at 0x7fa19b8a6c10>
        return position  # 将创建的地址空间对象返回,交给__init__方法接收

    # 实例化对象
    def __init__(self, name, age):
        self.name = name  # 在__new__方法返回的内存空间地址中放置name属性
        self.age = age  # 在__new__方法返回的内存空间地址中放置age属性
        # print(self)  # <__main__.People object at 0x7fa19b8a6c10>
        print("调用__init__初始化方法")

    # 对象作为函数调用时的逻辑
    def __call__(self, args):
        print("调用__call__方法,接收到的参数为:%s" % args)

    # 删除对象: 在(del 对象名后所对应的地址空间无任何引用时)或者程序执行结束之后
    def __del__(self):
        print("调用__del__析构方法,删除对象,释放内存空间")

    # 自定义print(对象名)时的输出内容
    def __str__(self):
        return '对象的name是:' + self.name + ',对象的age是:' + str(self.age)


if __name__ == '__main__':
    p = People('liuming'20)
    # print(p)  # <__main__.People object at 0x7fa19b8a6c10>
    p('abc')  # 调用__call__方法
    p1 = p
    p2 = p
    p3 = p  # 截止到这里p对象所在的地址空间,共有4个对象都在引用,分别是对象:p,p1,p2,p3
    del p3  # 删除的是p3对内存地址空间的引用关系,此时p对象所在的地址空间,共有3个对象在引用,分别是对象:p,p1,p2
    del p2
    del p1
    del p  # 自动调用__del__方法,因为p对象所在的地址空间已经没有任何对象在引用了,所以需要对内存地址进行回收释放
    p4 = People('xiaohong'18)
    print(p4)  # 对象的name是:xiaohong,对象的age是:18---注意:此时输出的不再是地址空间值了,而是__str__函数自定义return的内容
    print(str(p4))  # 输出内容同print(p4)
2. 结果输出
1.调用__new__构造方法
2.调用__init__初始化方法
3.调用__call__方法,接收到的参数为:abc
4.调用__del__析构方法,删除对象,释放内存空间
5.调用__new__构造方法
6.调用__init__初始化方法
7.对象的name是:xiaohong,对象的age是:18
8.对象的name是:xiaohong,对象的age是:18
9.调用__del__析构方法,删除对象,释放内存空间
3. 代码分析
  1. p = People('liuming', 20)p4 = People('xiaohong', 18)该代码块执行时都会自动调用__new____init__函数,对应结果输出为:第1,2,5,6行

  2. p('abc')该代码块执行时会自动调用__call__函数,对应结果输出为:第3行

  3. del p该代码块执行时会自动调用__del__函数,对应结果输出为:第4行

  • 注意:当执行代码块del p3/p2/p1时都没有自动调用__del__函数

  • 是因为此时p对象所指向的地址空间还有p这个对象在引用,指针引用关系还存在

  • 直到del p执行时才将该地址空间唯一的指针引用关系给销毁了,所以就调用了__del__函数。

  1. print(p4)print(str(p4))该代码块执行时会自动调用__str__函数,对应结果输出为:第7,8行

  2. 所有代码块全部执行完毕后,Python解释器的垃圾回收机制会将分配的内存进行释放回收,此时也会调用__del__函数,对应结果输出为:第9行

分类:

后端

标签:

Python

作者介绍

Wu_Candy
V1