Python魔术方法
在Python中,所有以“__”双下划线包起来的方法,都统称为“Magic Method”,这里对一些常用的魔术方法进行总结
1、特殊的一些通用属性
魔术方法 |
功能 |
name |
类、函数、方法等的名字 |
module |
类定义所在的模块 |
class |
对象或类所属的类 |
bases |
当前类的基类(父类) |
doc |
类、函数的文档帮助,没有定义为None |
mro |
Method Resolution Order 方法解析顺序 |
dict |
类或实例的属性,可写的字典,包含一个类的各种属性方法 |
dir |
返回类或者对象的所有成员名称列表 |
2、 对象的创建、初始化、销毁
魔术方法 |
功能 |
new |
对象创建 |
init |
对象初始化 |
del |
对象的销毁 |
当生成对象之前先调用的是new方法,接受的参数是cls类,然后返回类的实例,
当对象创建完成后,接受self参数需要对对象进行初始化,调用的就是init方法,
当对象的生命周期调用结束时,调用的是del析构方法,进行对象的删除,释放变量信息
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| class Student(object): def __new__(cls, name): print('正在new.....') return super(Student, cls).__new__(cls) def __init__(self, name): print("正在初始化对象.....") self.name = name def __del__(self): print("正在删除对象.....")
s = Student('张三') print(s.name)
|
回想一下之前写过的单例模式中实现的一个方法,就是在init之前先在new方法中判断实例是否存在,如果存在,就返回已经存在的实例,如果不存在再创建新的实例
3、 属性控制访问
1 2 3
| __getattr__(self, name):
|
1 2
| __setattr__(self, name, value)
|
1 2 3 4
| __getattribute__(self, name):
|
实例代码:
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
| class Access(object):
def __getattr__(self, name): print('__getattr__') return super(Access, self).__getattr__(name)
def __setattr__(self, name, value): print('__setattr__') return super(Access, self).__setattr__(name, value)
def __delattr__(self, name): print('__delattr__') return super(Access, self).__delattr__(name)
def __getattribute__(self, name): print('__getattribute__') return super(Access, self).__getattribute__(name)
access = Access() access.attr1 = True access.attr1 try: access.attr2 except AttributeError: pass del access.attr1
|
4、自定义容器的方法
可以利用 setitem 、getitem、 iter 等等实现可变容器和不可变的容器,例如可变(list.dict),不可变(string,tuple).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| __len__(self):
__getitem__(self,key):
__setitem__(self,key,value):
__delitem__(self,key):
__reversed__(self):
__contains__(self, item):
__missing__(self, key):
|
5、反射
1 2 3 4
| __instancecheck__(self, instance):
__subclasscheck__(self, subclass):
|
6、可调用对象
在Python中,一个特殊的魔术方法可以让类的实例的行为表现的像函数一样,你可以调用它们,将一个函数当做一个参数传到另外一个函数中等等。这是一个非常强大的特性。
1 2 3
| __call__(self, [args...]):
|
应用实例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| class Entity: """ 调用实体来改变实体的位置 """ def __init__(self, x, y): self.x, self.y = x, y def __call__(self, x, y): """ 改变实体的位置 """ self.x, self.y = x, y
e = Entity(3,5) e(5,6) print(e.x,e.y)
'''output:
5 6
'''
|
7、上下文管理
还记得在打开文件的with语句吗,在with声明的代码段中,我们可以做一些对象的开始操作和退出操作,还能对异常进行处理。这需要实现两个魔术方法: enter 和 exit。
1 2 3 4 5 6
| __enter__(self):
__exit__(self, exception_type, exception_value, traceback):
|
例如:
1 2 3
| with open('foo.txt') as bar:
|
8、复制
1 2 3 4 5 6
| __copy__(self):
__deepcopy__(self, memodict={}):
|
9、总结
学习魔术方法,会让我们对于平时调用函数或者使用一些内置方法时更明白其原理,在后面的学习中我也会尝试使用魔术方法来实现一些基础的类作为实践
10、参考文章
https://www.cnblogs.com/pyxiaomangshe/p/7927540.html