一、魔术方法
1、call :实例直接调用,需要定义__call__方法
- 未定义__call__方法时:
class Test:
def __init__(self, num):
self.num = enumerate
def __add__(self, other):
print(self.num)
print(other.num)
res = self.num + other.num
return res
a = Test(8)
a() #TypeError: 'Test' object is not callable
- 定义__call__方法后:
class Test:
def __init__(self, num):
self.num = enumerate
def __add__(self, other):
print(self.num)
print(other.num)
res = self.num + other.num
return res
def __call__(self):
print("调用成功")
a = Test(8)
a() # 调用成功
2、其他魔术方法
class Test:
"""我是一个测试类"""
def __init__(self, num):
self.num = enumerate
def __add__(self, other):
print(self.num)
print(other.num)
res = self.num + other.num
return res
def __call__(self):
print("调用成功")
a = Test(8)
a() # 调用成功
# 其他魔术方法
print(a.__class__) # 查看类名<class '__main__.Test'>
print(a.__dict__) # 查看全部属性{'num': <class 'enumerate'>}
print(a.__doc__) # 查看类的注释部分,查看对象文档 #我是一个测试类
二、单例模式
1、new 方法:
类只能被实例化一次,也就是说我们的类实例化时,只是变量名不同,但是始终是一个类
- 使用__new__ 方法前:
class Earth:
def __init__(self):
self.name = 'earth'
e = Earth()
print(e, id(e))
f = Earth()
print(f, id(f))
'''
<__main__.Earth object at 0x000001ED22BA7780> 2118001522560
<__main__.Earth object at 0x000001ED22BAF9E8> 2118001555944
e与f内存地址不一样
'''
- 使用__new__ 方法后:不管实例多少次,都始终是一个对象。即:加了__new__方法后相当于只实例化了一次
注: new 是在__init__前面执行的
是固定的模式,记住就好
class Earth(object):
def __new__(cls):
if not hasattr(cls, "instance"):
cls.instance = super().__new__(cls)
return cls.instance
def __init__(self):
self.name = 'earth'
e = Earth()
print(e, id(e))
f = Earth()
print(f, id(f))
'''
<__main__.Earth object at 0x0000020297084B00> 2210147093248
<__main__.Earth object at 0x0000020297084B00> 2210147093248
使用了__new__方法后,e和f的内存地址相同
'''
2、定制属性访问
即对属性的操作:增删改查
- 增、改(无则新增,有则改)
setattr() 或 setattr()
- 删
delattr() defattr() 或 del
- 查:hasattr,getattr , getattr
3、描述符
函数执行的底层——>魔术方法——>自定义
- 正常情况下实例化另一个类
class Test:
pass
class Test1:
a = Test() #上一个类的实例化拿来做这一个类的方法,这就是描述符
- 增删改查方法的扩展
class Test:
def __get__(self, instance, owner):
print("__get__")
def __set__(self, instance, value):
print("__set__")
def __delete__(self, instance):
print("__delete__")
class Test1:
def __init__(self):
self.name = 'vae'
a = Test() #上一个类的实例化拿来做这一个类的方法,这就是描述符
b = Test1() # 类的实例化
print(b.name) # 获取对象属性
b.a # 会去找__get__方法
b.a = 99 # 会去找__set__方法
del b.a # 会去找__delete__方法