点击上方蓝字关注我们

1
定义
魔术方法就是一个类/对象中的方法,和普通方法唯一的不同是:
普通方法需要主动调用!而魔术方法是在特定时刻自动触发。
2
常用魔术方法
1.__init__(self): 初始化魔术方法, 用于初始化对象的属性
触发时机:初始化对象时触发
2.__new__(cls): 实例化魔术方法, 实例化对象, 必须返回一个对象实例
触发时机:在实例化对时触发
实例化一个对象时: 首先会触发__new__, 然后才会触发__init__
使用这个魔术方法典型应用就是单例模式, 小例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| # -*- coding: utf-8 -*- # @Author: Mehaei # @Date: 2023-08-05 18:01:36 # @Last Modified by: Mehaei # @Last Modified time: 2023-08-05 18:17:37 class Home(object): instance = None """docstring for Home""" def __init__(self, *arg): super(Home, self).__init__() self.arg = arg print("调用__init__") def __new__(cls): print("调用__new__") if not cls.instance: cls.instance = object.__new__(cls) return cls.instance home = Home() print(id(home)) home = Home() print(id(home)) # 正常实例化两次对象 # 输出 ''' 调用__init__ 4530165240 调用__init__ 4530558512 [Finished in 0.1s] ''' # 单例模式输出 ''' 调用__new__ 调用__init__ 4305778224 调用__new__ 调用__init__ 4305778224 '''
|
3.__del__(self): 删除对象魔术方法
触发时机:当对象没有用(没有任何变量引用)的时候被触发
注意:手动使用del删除一个对象时不一定会触发当前方法,
只有当前对象没有任何变量接收使用时才会触发
4.__call__(self): 调用对象的魔术方法
触发时机:将对象当作函数调用时触发 实例化对象()
5.__len__(self): 查看对象的长度(一般用于迭代器), 必须返回一个整型
触发时机: 使用len(对象) 的时候触发
6.__str__(self): 查看对象信息, 必须返回字符串
触发时机: 使用print(对象)或者str(对象)的时候触发
7.__repr__(self): 查看对象信息, 必须返回字符串
触发时机: 在使用repr(对象)的时候触发
8.__bool__(self): 对象转为布尔值, 必须返回布尔值
触发时机: 使用bool(对象)的时候触发
9.__format__(self, ftype): 格式化对象, 必须返回字符串
触发时机:使用字符串.format(对象)时候触发
10.__getattr__(self, attr): 获取对象成员
触发时机:获取不存在的对象成员时触发
11.__setattr__(self, attr, value): 设置对象成员
触发时机:设置对象成员值的时候触发
12.__delattr__(self, attr): 删除对象成员
触发时机:删除对象成员时触发
下面是使用的小例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
| # -*- coding: utf-8 -*- # @Author: Mehaei # @Date: 2023-08-05 18:01:36 # @Last Modified by: Mehaei # @Last Modified time: 2023-08-05 20:46:49 class Home(object): instance = None """docstring for Home""" def __init__(self, *arg): super(Home, self).__init__() self.arg = arg print("调用__init__") def __new__(cls): print("调用__new__") if not cls.instance: cls.instance = object.__new__(cls) return cls.instance def __del__(self): print("调用__del__") def __call__(self): print("调用__call__") # 默认返回None, 可以自定义返回内容 return int def __len__(self): print("调用__len__") return 10 def __str__(self): print("调用__str__") return 'this is home' def __repr__(self): print("调用__repr__") return 'this is home repr' def __getattr__(self, attr): print(f"调用__getattr__ {attr}") def __setattr__(self, attr, value): print(f"调用__setattr__{attr}:{value}") def __delattr__(self, attr): print(f"调用__delattr__ {attr}") # 实例化对象时, 首先调用__new__, 然后调用__init__ home = Home() ''' 输出: 调用__new__ 调用__init__ ''' # # 对象没有被任何地方使用时, 调用__del__ # del home ''' 输出: 调用__del__ ''' # # 把实例化对象当函数调用时触发 # home = Home()() # 输出: <class 'int'> # print(home) # print(len(home)) ''' 输出: 调用__len__ 10 ''' # print(home) # """ # 调用__str__ # this is home # """ # str(home) # """ # 调用__str__ # """ # repr(home) # """ # 调用__repr__ # """ # print(repr(home)) # """ # 调用__repr__ # this is home repr # """ # home.a # # 调用__getattr__ a # home.a = 1 # # 调用__setattr__a:1 # del home.a # # 调用__delattr__ a # 在最后没有任何地方使用的时候, 也会调用del ''' 调用__del__ '''
|
3
上下文管理魔术方法
__enter__(self): with代码块初始化操作
1. 定义当使用 with 语句时的初始化行为
2. enter 的返回值被 with 语句的目标或者 as 后的名字绑定
__exit__(self, exctype, excvalue, traceback): with代码块结束后的操作
1. 定义当一个代码块被执行或者终止后上下文管理器应该做什么
2. 一般被用来处理异常,清除工作或者做一些代码块执行完毕之后的日常工作
读写文件时, 使用的 **with open() as f:f.read()**就使用这两个魔术方法
小例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| # -*- coding: utf-8 -*- # @Author: Mehaei # @Date: 2023-08-05 18:01:36 # @Last Modified by: Mehaei # @Last Modified time: 2023-08-05 20:28:23 class FileOpt(object): def __init__(self, fname): self.fname = fname self.fp = open(fname, "r+") def __enter__(self): print("调用__enter__") return self.fp def __exit__(self, exctype, excvalue, traceback): print("调用__exit__", exctype, excvalue, traceback) self.fp.close() with FileOpt("mq_learn.py") as fp: print(len(fp.read())) # 输出 ''' 调用__enter__ 165 调用__exit__ None None None '''
|
4
这篇结束了!
还有一些描述符, 运算, 类型转换, 容器相关的魔术方法,
这里就不一一介绍了, 因为实在太多了, 后面用到了再介绍,
在实际开发中, __init__是使用频率最多的, 其次是__new__,
掌握这俩个魔术方法, 在开发中基本就不会有问题了
今日推荐
python代码注释率统计脚本
python中的类和对象
python常用模块及方法
python常用内置函数

点个在看你最好看
