Python的魔术方法小结
特殊属性
属性 | 含义 |
---|---|
__name__ | 类、函数、方法的名字 |
__module__ | 类定义所在的模块名 |
__class__ | 对象或类所属的类 |
__bases__ | 类的基类的元组 |
__doc__ | 类、函数的文档字符串,如果没有定义则为None |
__mro__ | 类的mro,class.mro()返回的结果保存在此 |
__dict__ | 类或者实例的属性,可写的字典 |
__dir__ | 返回类或者对象的所有成员名称列表,dir()函数就是调用__dir__().如果提供__dir__(),则返回属性的列表,否则会尽量从__dict__属性中收集信息 |
魔术方法
分类
__hash__
class A:
def __init__(self, name, age=18):
self.name = name
def __hash__(self):
return 1
def __repr__(self):
return self.name
print(hash(A('tom')))
print((A('tom'),A('tom')))
print([A('tom'),A('tom')])
print('~~~~~~~~~~~~~')
s = {A('tom'),A('tom')}
print(s)
print({tuple('t'),tuple('t')})
print({('tom',),('tom',)})
print({'tom','tom'})
class A:
def __init__(self,name,age=18):
self.name = name
def __hash__(self):
return 1
def __eq__(self,other):
return self.name == other.name
def __repr__(self):
return self.name
print({A('tom'),A('tom')})
__eq__
__bool__
可视化魔术方法
__repr__ 内建函数repr()对一个对象获取字符串表达,调用该方法返回字符串表达,如果__repr__也没有定义,就直接返回object的定义,显示内存地址信息
__str__
__bytes__
class A:
def __init__(self,name,age=18):
self.name = name
self.age = age
def __repr__(self):
return 'repr:{},{}'.format(self.name,self.age)
def __str__(self):
return 'str: {},{}'.format(self.name,self.age)
def __bytes__(self):
import json
return json.dumps(self.__dict__).encode()
print(A('tom'))
print([A('tom')]) # 调用了列表的__repr__
print([str(A('tom'))])
运算符重载
运算符 | 特殊方法 | 含义 |
---|---|---|
<,<=,==,>,>=,!= | __lt__,__le__,__eq__,__gt__,__ge__,__ne__ | 比较运算符 |
+,-,*,/,%,/,**,divmod | __add__,__sub__,__mul__,__truediv__,__mod__,__floordiv__,__pow__,__divmod__ | 算术运算符,移位、位运算也有对应的方法 |
@functools.total_ordering装饰器
容器相关方法
方法 | 意义 |
---|---|
__len__ | 内建函数len(),返回对象的长度,如果把对象当容器类型看,就如同list或者dict。__boool__函数调用的时候,如果没有__bool__()方法,则会看__len__()方法是否存在,存在即返回非0为真 |
__iter__ | 迭代容器时调用,返回一个新的迭代器 |
__contains__ | in成员运算符,没有实现就调用__iter__方法遍历 |
__getitem__ | 实现self[key]访问。序列对象,key接受整数为索引,或者切片。对于set和dict,key为hashable。key不存在则引发keyerror异常 |
__setitem__ | 和__getitem__的访问类似,是设置值的方法 |
__missing__ | 字典或其子类使用。getitem()调用时,key不存在执行该方法 |
可调用对象
上下文管理
class Point:
def __init__(self):
print('init')
def __enter__(self):
print('enter')
def __exit__(self,exc_type,exc_val,exc_tb):
print('exit')
with Point() as f:
print('do sth')
参数
class Point:
def __init__(self):
print('init')
def __enter__(self):
print('enter')
return
def __exit__(self,exc_type,exc_val,exc_tb):
print(exc_type)
print(exc_val)
print(exc_tb)
print('exit')
return "abc"
p=Point()
with p as f:
raise Exception('New Error')
print('do sth')
print('outer')
上下文应用场景
contextlib.contextmanager
反射相关的函数和方法
反射内置函数
class Point:
def __init__(self,x,y):
self.x = x
self.y = y
def __str__(self):
return "Point({},{})".format(self.x, self.y)
def show(self):
print(self)
p1 = Point(4,5)
p2 = Point(10,10)
print(repr(p1),repr(p2),sep='\n')
print(p1.__dict__)
setattr(p1,'y',16)
setattr(p1,'z',10)
print(getattr(p1,'__dict__'))
# 动态增加方法
# 为类增加方法
if not hasattr(Point,'add'):
setattr(Point,'add',lambda self,other: Point(self.x + other.x, self.y + other.y))
print(Point.add)
print(p1.add)
print(p1.add(p2)) # 绑定
# 为示例增加方法,未绑定
if not hasattr(p1,'sub'):
setattr(p1,'sub',lambda self,other:Point(self.x - other.x, self.y - other.y))
print(p1.sub(p1,p1))
print(p1.sub)
# add在谁里面,sub在谁里面
print(p1.__dict__)
print(Point.__dict__)
反射相关的魔术方法
__getattr__()
class Base:
n = 0
class Point(Base):
z = 6
def __init__(self,x,y):
self.x = x
self.y = y
def show(self):
print(self.x,self.y)
def __getattr__(self,item):
return "missing {}".format(item)
p1 = Point(4,5)
print(p1.x)
print(p1.z)
print(p1.n)
print(p1.t) # missing
setattr()
class Point(Base):
z = 6
def __init__(self,x,y):
self.x = x
self.y = y
def show(self):
print(self.x,self.y)
def __getattr__(self,item):
return "missing {}".format(kry,value)
def __setattr__(self,key,value):
print("setattr {}={}".format(key,value))
self.__dict__[key] = value
__getattribute__方法
class Base:
n = 0
class Point(Base):
z = 6
def __init__(self,x,y):
self.x = x
self.y = y
def __getattr__(self,item):
return "missing {}".format(item)
def __getattribute__(self,item):
return item
p1 = Point(4,5)
print(p1.__dict__)
print(p1.x)
print(p1.z)
print(p1.n)
print(p1.t)
print(Point.__dict__)
print(Point.z)
链接:https://blog.csdn.net/syaziou/article/details/109081794
(版权归原作者所有,侵删)
微信扫码关注该文公众号作者
戳这里提交新闻线索和高质量文章给我们。
来源: qq
点击查看作者最近其他文章