1 python運算符重載之成員關系和屬性運算
1.1 重載成員關系運算符
1.1.1 contains,iter,getitem
python使用成員關系運算符in時,
按優先級調用方法:contains>iter>getitem;
class MyIters:def __init__(self,value):self.data=valuedef __getitem__(self,i):print('get[{}]:'.format(i),end='')return self.data[i]#def __iter__(self):# print('iter=> ',end='')# self.ix=0# return self#def __next__(self):# print('next:',end='')# if self.ix==len(self.data):# raise StopIteration# item=self.data[self.ix]# self.ix+=1# return item#def __contains__(self,x):# print('contains: ',end='')# return x in self.dataif __name__ == '__main__':mi=MyIters('tyxt')print('t' in mi)# in 按 contains > iter> getitem順序調用for i in mi:# for 調用 iter 和 next 、 getitemprint(i,end=' | ')print()print([i*2 for i in mi])print(list(map(ord,mi)))i=iter(mi)while True:try:print(next(i),end='#')except StopIteration:break
''' #未注釋contains,按contains>iter>getitem順序調用
E:\documents\F盤>python myIn.py
contains: True
iter=> next:t | next:y | next:x | next:t | next:
iter=> next:next:next:next:next:['tt', 'yy', 'xx', 'tt']
iter=> next:next:next:next:next:[116, 121, 120, 116]
iter=> next:t#next:y#next:x#next:t#next:
E:\documents\F盤>
'''
''' #注釋contains,按contains>iter>getitem順序調用
E:\documents\F盤>python myIn.py
iter=> next:True
iter=> next:t | next:y | next:x | next:t | next:
iter=> next:next:next:next:next:['tt', 'yy', 'xx', 'tt']
iter=> next:next:next:next:next:[116, 121, 120, 116]
iter=> next:t#next:y#next:x#next:t#next:
'''
''' #注釋contains 和 iter ,按contains>iter>getitem順序調用
E:\documents\F盤>python myIn.py
get[0]:True
get[0]:t | get[1]:y | get[2]:x | get[3]:t | get[4]:
get[0]:get[1]:get[2]:get[3]:get[4]:['tt', 'yy', 'xx', 'tt']
get[0]:get[1]:get[2]:get[3]:get[4]:[116, 121, 120, 116]
get[0]:t#get[1]:y#get[2]:x#get[3]:t#get[4]:
'''
1.2 重載屬性運算符
1.2.1 getattr
python的__getattr__方法,攔截不存在的或未定義的屬性點號運算。
>>> class MyGet:# 通過點號運算訪問不存在的屬性時自動調用getattrdef __getattr__(self,attr):if attr=='name':return '梯閱線條'else:raise AttributeError(attr)
>>> mg=MyGet()
>>> mg.name
'梯閱線條'
>>> mg.age
Traceback (most recent call last):File "<pyshell#28>", line 1, in <module>mg.ageFile "<pyshell#25>", line 6, in __getattr__raise AttributeError(attr)
AttributeError: age
# 存在的屬性不會調用getattr
>>> mg.addr='深圳'
>>> mg.addr
'深圳'
1.2.2 setattr
python的__setattr__方法,會攔截全部的屬性賦值語句。
實現__setattr__方法時,必須通過屬性字典進行賦值,
如果通過點號賦值,會自動調用__setattr__方法,進入無限循環,導致堆棧溢出程序異常。
>>> class MySet:# 通過點號運算給屬性賦值時自動調用 setattr 方法def __setattr__(self,attr,value):if attr=='name':# 必須通過字典屬性賦值方式實現self.__dict__[attr]=valueelse:raise AttributeError(attr+' 禁止設置')
>>> ms=MySet()
>>> ms.name='梯閱線條'
>>> ms.name
'梯閱線條'
>>> ms.age=9555
Traceback (most recent call last):File "<pyshell#43>", line 1, in <module>ms.age=9555File "<pyshell#39>", line 6, in __setattr__raise AttributeError(attr+' 禁止設置')
AttributeError: age 禁止設置
1.2.3 私有屬性列表
通過setattr攔截屬性賦值,如果在私有屬性列表里面,禁止賦值。
>>> class MyPrivateExc(Exception):pass
>>> class MyPrivacy:def __setattr__(self,attr,value):# 私有變量名列表,禁止賦值操作if attr in self.privates:raise MyPrivateExc(attr,self)else:self.__dict__[attr]=value
>>> class MyTest1(MyPrivacy):privates=['age']
>>> class MyTest2(MyPrivacy):privates=['name','pay']def __init__(self):self.__dict__['name']='梯閱線條'
>>> mt1=MyTest1()
>>> mt2=MyTest2()
>>> mt1.name='張三'
>>> mt2.name='李四'
Traceback (most recent call last):File "<pyshell#71>", line 1, in <module>mt2.name='李四'File "<pyshell#52>", line 4, in __setattr__raise MyPrivateExc(attr,self)
MyPrivateExc: ('name', <__main__.MyTest2 object at 0x00E3F650>)
>>> mt1.age=9555
Traceback (most recent call last):File "<pyshell#72>", line 1, in <module>mt1.age=9555File "<pyshell#52>", line 4, in __setattr__raise MyPrivateExc(attr,self)
MyPrivateExc: ('age', <__main__.MyTest1 object at 0x00E3F630>)
>>> mt2.age=9555
>>> mt2.age
9555
>>> mt2.name
'梯閱線條'