/** * 使用匿名函数实现操作封装 * 将匿名函数作为 map 的键值,通过命令行参数动态调用匿名函数 * 运行命令 go run src/hh/main.go --skill=fly */
顺晟科技
2021-06-16 10:45:01
435
序
之前已经总结了关键字、运算符和magic方法的对应关系,下面总结了python内置函数对应的magic方法。
魔术方法
数学计算
abs(args):返回值,调用_ _ abs _ _
Round(args):返回舍入值并调用_ _ round _ _
Math.floor():向下舍入并调用_ _ floor _ _
Math.ceil():向上舍入,调用_ _ ceil _ _
Math.trunc():找到一个值最接近0的整数,调用_ _ trunc _ _
Divmod(a,b):返回商和余数,调用_ _ divmod _ _
Pow(a,b):回电,调用_ _ pow _ _
Sum():返回并调用_ _ sum _ _
Float():转换小数,调用_ _ float _ _
Int():转换整数,调用_ _ int _ _
Str():转换字符串并调用_ _ str _ _
Sys.getsizeof():内存中对象的大小,调用_ _ sizeof _ _
Bin(*args,**kwargs):调用参数的__bin__方法,返回整数的二进制表示,只支持一个参数和int类型
Hash():调用__hash__方法获取对象的哈希值。两个数相等的哈希值相等,但反过来不一定成立。
十六进制(*args,**kwargs):调用__hex__方法查找整数的十六进制表示,只支持int类型
Oct(*args,**kwargs):调用__oct__方法查找Integer的八进制表示,只支持int类型
访问控制
_ _ getattr _ _ (self,name) : getattr方法被触发,该方法仅对对象的未定义属性有效,也就是说,如果视图得到一个不存在的属性,如果对象没有定义__getattribute__(self,name)方法,将调用该方法;
__getattr__ (self,name):getattr方法被触发。如果对象定义了此方法,则必须触发它。将不会调用_ _ getattr _ _方法。也可以由self.name语法sugar触发;
_ _ setattr _ _ (self,name,value):由setattr方法触发,设置一个对象的属性;也可以由self.name=' '语法糖触发。
_ _ delattr _ _ (self,name):由delattr方法触发删除对象的属性,或由delattr.name触发;
容器类型
在Python中实现自定义容器类型需要一些协议。不变的容器类型有以下协议:
不可变容器,需要定义_len_和_ getitem _
变量容器需要定义_len_、_getitem_、_setitem_、_ delivery _
容器可以迭代,并且需要定义_ ITER。
迭代器,必须遵守迭代器协议,需要定义_iter_和_next_方法。
索引语法糖和魔术方法
__len__(self):返回容器的长度;
__getitem__(self,key):使用self[key]的语法获取sugar元素,会触发;
__setitem__(self,key): self[key]=' XXX '形式的复制将触发;
_ _ delivery _ _ (self,key) :使用del self[key]语法触发sugar
_ _ reversed _ _(self): reversed(self)触发器反转容器;
__missing__(self,key):如果元素没有触发器,则字典结构以self[key]的形式获取元素;
切片语法糖和魔术方法
py2和py3在底层切片的原理上差别很大。py2使用三种神奇的方法:_getslice_、_setslice_、_delslice_,而py3通过_getitem_、_setitem_、_ delivery _来控制索引和切片。
#在py 2中
ls=[1,2,3,4]
print中的语法sugar(ls[1:3])# py2调用__getslice__方法,该方法在py3中被丢弃
Dells [1:3] #此语法sugar调用py 2中的__delslice__方法,该方法在py3中被丢弃
Ls [1:3]=[1,2,2] #语法sugar调用py2中的__setslice__方法,该方法在py3中被丢弃
#在py 3中
类别人员(对象):
def __getitem__(self,item):
打印(项目)
返回“getitem”
def __setitem__(self,key,value):
打印(键、值)
返回“setitem”
def __delitem__(self,key):
打印(键)
返回“delitem”
if __name__=='__main__':
人=人()
print(person[0])# person[0]==person。__getitem__(0)
print(person[0:2])# person[0:2]==person。__getitem__(切片(0,2,无))
person[0:2]=' test ' #==person。__setitem__(切片(0,2,无),“测试”)
del person[0:2] #==person。__delitem__(切片(0,2,无))
#结果
0
生成物品
切片(0,2,无)
生成物品
切片(0,2,无)测试
切片(0,2,无)
python在处理索引语法sugar时,会将索引作为一个参数,传递给相关的getitem、setitem和delivery这些神奇的方法。在处理切片语法糖时,调用切片方法获取切片实例对象,并调用相关魔术方法作为参数。
复制
__copy__(self):如果对象定义了此方法,copy.copy()将调用此方法返回复制的对象;
__deepcopy__(self,x):如果对象定义了此方法,copy.deepcopy()将调用此方法返回复制的对象;
连载
序列化可以简单理解为任何数据的描述方法。如果多个平台遵循相同的序列化协议,那么传输数据会很方便。Python的默认序列化模块是pickle。
序列化的一个简单例子
类别人员(对象):
def __init__(self):
self.name='cai '
if __name__=='__main__':
进口泡菜
人=人()
带open('。/person.txt ',' wb') as f:
#序列化后存储
pickle.dump(person,f)
带open('。/person.txt ',' rb') as f:
#反序列化
per=pickle.load(f)
打印(按姓名)
#我们可以保存一个类,然后直接阅读使用。
相关魔术方法
__getinitargs__(self):这种魔法方法在py3里好像被抛弃了。原函数是在序列化时获取实例化参数,应该返回一个元组;
__getnewargs__(self):对于一个新类,通过此方法在反pickle期间更改传递给__new__的参数;应该返回一个参数元组。
__getstate__(self):定义对象序列化时的状态,而不是使用对象的__dict__属性,必须返回一个字典,该字典将替换__dict__属性并在序列化过程中被调用;
__setstate__(self,state):当对象反pickle时,如果定义了__setstate__,对象的状态将传递给这个magic方法,而不是直接应用到对象的__dict__属性,状态参数是序列化前的__dict__属性。
类别人员(对象):
def __init__(self,name):
打印(“初始化”)
self.name=name
def __getinitargs__(self):
打印(' initargs ')
返回'赵',
def __getnewargs__(self):
打印(' newargs ')
返回'王',
def __getstate__(self):
打印(' getstate ')
返回{'name':'xiao'}
def __setstate__(self,state):
打印('设置状态')
打印(状态)
自我。_ _ dict _ _=状态
if __name__=='__main__':
进口泡菜
人=人(“才”)
带open('。/person.txt ',' wb') as f:
#序列化后存储
pickle.dump(person,f)
带open('。/person.txt ',' rb') as f:
#反序列化
per=pickle.load(f)
打印(按姓名)
#结果
__新_ _
初始化
newargs
方法
__新_ _
设置
{'name': 'xiao'}
箫
描述:
在拾取序列化对象之前,请执行__getnewargs__或__new__方法的参数;
然后执行__getstate__方法,返回值替换对象的__dict__属性值;
反序列化时,调用新方法并使用getnewargs返回的值作为参数创建一个实例;
最后调用__setstate__方法,以getstate方法的返回值作为状态参数;
因此,因为在反序列化过程中初始化不会调用init方法,所以getinitargs和getnewargs方法的作用并不显著;
其他的
_ _ instancecheck _ _(自身,实例):实例触发器确定对象的类型
_ _子类check _ _ (self,subclass) :由子类触发,判断一个对象是另一个对象的子类;
__call__:callable触发器,判断一个对象是否可以调用;
由__dir__(self):dir()触发,获取对象所有属性和方法名称列表;
__str__和__repr__
调用str triggers _str_,并调用repr()触发器_repr_,但是print()也可以触发__str__和_ _ repr _。如果对象定义了_str_,print()通常会触发_str_,否则,_ repr _但是像列表和字典这样的容器总是使用_repr_方法。
__str__和__repr__
一般来说_str_的返回结果可读性强,而_repr_的返回结果准确性好。
默认情况下,当需要__str__方法但找不到时,会自动调用_repr_方法。
摘要
熟悉了python语法糖、内置函数、魔术方法之间的关系后,写一个优雅易用的类显然是有帮助的。
16
2021-06
16
2021-06
16
2021-06
16
2021-06
16
2021-06
16
2021-06