06_05、魔术方法

在Python中,所有以“__”双下划线包起来的方法,都统称为“Magic Method”,中文称『魔术方法』,例如类的初始化方法 __init__

Python的Class机制内置了很多特殊的方法来帮助使用者高度定制自己的类,这些内置方法都是以双下划线开头和结尾的(__),会在满足某种条件时自动触发

1、__str__

__str__方法会在对象被打印时自动触发,print功能打印的就是它的返回值,我们通常基于方法来定制对象的打印信息,该方法必须返回字符串类型

class People:
    # 初始化类
    def __init__(self, name, age):
        self.name = name
        self.age = age
        
    # __str__方法
    def __str__(self):
        return '<Name:%s Age:%s>' % (self.name, self.age)  # 返回类型必须是字符串


p = People('lili', 18)
print(p)  # 触发p.__str__(),拿到返回值后进行打印
# <Name:lili Age:18>

2、__del__

    1. del 删除对象的时候自动触发
    2. 当整个程序执行完毕再调用方法

class Student():
    def __init__(self, name, age):
        self.name = name
        self.age = age
        # self.f = open('a.txt')

    # 1. del 删除对象的时候自动触发
    # 2. 当整个程序执行完毕再调用方法,用来在对象被删除时自动触发回收系统资源的操作
    def __del__(self):
        print('触发了')
        # self.f.close()


stu = Student('tom', 19)
del stu
print(123)

3、__enter__和__exit__

with语句,也叫做上下文管理协议

为了让一个对象兼容with语句,必须在这个对象的类中声明__enter__和__exit__方法

class Open:
    def __init__(self, name):
        self.name = name

    def __enter__(self):
        print('出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量')
        # return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('with中代码块执行完毕时执行我啊')


with Open('a.txt') as f:
    print('=====>执行代码块')

__exit__()中的三个参数分别代表异常类型,异常值和追溯信息,with语句中代码块出现异常,则with后的代码都无法执行

如果__exit()返回值为True,那么异常会被清空,就好像啥都没发生一样,with后的语句正常执行

4、__setattr__,__delattr__,__getattr__

06_05、魔术方法
 1 class Foo:
 2     x=1
 3     def __init__(self,y):
 4         self.y=y
 5 
 6     def __getattr__(self, item):
 7         print('----> from getattr:你找的属性不存在')
 8 
 9 
10     def __setattr__(self, key, value):
11         print('----> from setattr')
12         # self.key=value #这就无限递归了,你好好想想
13         self.__dict__[key]=value #应该使用它
14 
15     def __delattr__(self, item):
16         print('----> from delattr')
17         # del self.item #无限递归了
18         self.__dict__.pop(item)
19 
20 #__setattr__添加/修改属性会触发它的执行
21 f1=Foo(10)
22 print(f1.__dict__) # 因为你重写了__setattr__,凡是赋值操作都会触发它的运行,你啥都没写,就是根本没赋值,除非你直接操作属性字典,否则永远无法赋值
23 f1.z=3
24 print(f1.__dict__)
25 
26 #__delattr__删除属性的时候会触发
27 f1.__dict__['a']=3  # 我们可以直接修改属性字典,来完成添加/修改属性的操作
28 del f1.a
29 print(f1.__dict__)
30 
31 #__getattr__只有在使用点调用属性且属性不存在的时候才会触发
32 f1.xxxxxx
View Code

5、isinstance(obj,cls)和issubclass(sub,super)

isinstance(obj,cls)检查是否obj是否是类 cls 的对象

issubclass(sub, super)检查sub类是否是 super 类的派生类

返回值为布尔类型

 

上一篇:Swoole实战之手撸HttpServer框架 9 使用方法注解 注册路由


下一篇:从零开始学mitmproxy抓包工具