魔法方法与特殊成员
目录
全部打印
for item in dir(top_k_metergroup): #top_k_metergroup是某类的一个实例化对象
print(item)
全局
1. __file__
打印的是命令所在py文件的文件名,如try.py
2. __slots__
核心参考(TODO)
结论:
当一个类需要创建大量实例时,可以使用__slots__
来减少内存消耗。如果对访问属性的速度有要求,也可以酌情使用。另外可以利用slots的特性来限制实例的属性。而用在普通类身上时,使用__slots__
后会丧失动态添加属性和弱引用的功能,进而引起其他错误,所以在一般情况下不要使用它
基础
是特殊方法的昵称,一般双下划线的函数,命名为dunder-getitem
class Cat:
"""
这是一只猫的类
"""
1. __init__
与__del__
def __init__(self,name, tail_length = 10):
self.name = name
self.__privatename = name #私有属性
self.tail_length = tail_length
print(f"I am a cat, names {name}")
def __del__(self):
print("我被系统回收了")
# usage
cat = Cat("crystal")
print(cat)
del cat
print(cat)
2. __call__
使得这个对象可以被调用,如同一个函数
def __call__(self, *args, **kwargs):
print("cat", args[0]+args[1])
print(callable(cat)) #检查cat是否可以被调用
3. __str__
在print(cat)
时可以按照合适的方式进行打印输出
def __str__(self):
return f"我是{self.name}\n"
# usage
print(cat)
print(str(cat))
4. __len__
len(cat)的输出模式
def __len__(self):
return self.tail_length
5. __iter__
使得cat可以被迭代
def __iter__(self):
return iter([1,2,3,4])
#usage
for i in cat:
print("cat",i)
6. 字典化
__getitem__
, __setitem__
, __delitem__
使得cat可以用类似于字典的方式进行内部成员访问,修改,删除
def __getitem__(self,key):
if key == 'name':
return self.name
else:
return None
def __setitem__(self, key, value):
if key == 'name':
self.name = value
def __delitem__(self, key, value):
if key == 'name':
del self.name
# __getitem__(), __setitem__(), __delitem__()
print(cat['name'])
cat['name'] = 'sniper'
print(cat['name'])
del cat['name']
7. 加减乘除操作
__add__
, __sub__
, __mul__
, __div__
, __mod__
, __pow__
def __add__(self, other):
if isinstance(other, Cat):
return [self, other]
elif isinstance(other, list):
return other.append(self)
# usage
cat1 = Cat('crystal')
cat2 = Cat('sniper', 15)
print(cat1 + cat2)
cats = cat1 + cat2
cat3 = Cat('Alen')
print(cat3 + cats)
8. 特殊成员__doc__
& __dict__
# __doc__
print(cat.__doc__)
print(cat.__module__)
print(cat.__class__)
# __dict__
print(cat.__dict__)
进阶
await,实现等待[1]
import asyncio
class Waiting:
def __await__(self):
yield from asyncio.sleep(2)
print("ok")
async def main():
await Waiting()
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
如果想要调用一些async def
的函数而不是asyncio.sleep
的话,无法通过如下方法实现
async def new_sleep():
await asyncio.sleep(2)
class Waiting:
def __await__(self):
yield from asyncio.sleep(2)
await new_sleep()
print("ok")
因为__await__
不是async
函数,不能够使用yeild
。因此可以通过如下方法解决
async def new_sleep():
await asyncio.sleep(2)
class Waiting:
def __await__(self):
return new_sleep().__await__()