python使用成员关系运算符in时,
按优先级调用方法:contains>iter>getitem;
class MyIters:
def __init__(self,value):
self.data=value
def __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.data
if __name__ == '__main__':
mi=MyIters('tyxt')
print('t' in mi)# in 按 contains > iter> getitem顺序调用
for i in mi:# for 调用 iter 和 next 、 getitem
print(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]:
'''
python的__getattr__方法,拦截不存在的或未定义的属性点号运算。
>>> class MyGet:
# 通过点号运算访问不存在的属性时自动调用getattr
def __getattr__(self,attr):
if attr=='name':
return '梯阅线条'
else:
raise AttributeError(attr)
>>> mg=MyGet()
>>> mg.name
'梯阅线条'
>>> mg.age
Traceback (most recent call last):
File "" , line 1, in <module>
mg.age
File "" , line 6, in __getattr__
raise AttributeError(attr)
AttributeError: age
# 存在的属性不会调用getattr
>>> mg.addr='深圳'
>>> mg.addr
'深圳'
python的__setattr__方法,会拦截全部的属性赋值语句。
实现__setattr__方法时,必须通过属性字典进行赋值,
如果通过点号赋值,会自动调用__setattr__方法,进入无限循环,导致堆栈溢出程序异常。
>>> class MySet:
# 通过点号运算给属性赋值时自动调用 setattr 方法
def __setattr__(self,attr,value):
if attr=='name':
# 必须通过字典属性赋值方式实现
self.__dict__[attr]=value
else:
raise AttributeError(attr+' 禁止设置')
>>> ms=MySet()
>>> ms.name='梯阅线条'
>>> ms.name
'梯阅线条'
>>> ms.age=9555
Traceback (most recent call last):
File "" , line 1, in <module>
ms.age=9555
File "" , line 6, in __setattr__
raise AttributeError(attr+' 禁止设置')
AttributeError: age 禁止设置
通过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 "" , line 1, in <module>
mt2.name='李四'
File "" , line 4, in __setattr__
raise MyPrivateExc(attr,self)
MyPrivateExc: ('name', <__main__.MyTest2 object at 0x00E3F650>)
>>> mt1.age=9555
Traceback (most recent call last):
File "" , line 1, in <module>
mt1.age=9555
File "" , line 4, in __setattr__
raise MyPrivateExc(attr,self)
MyPrivateExc: ('age', <__main__.MyTest1 object at 0x00E3F630>)
>>> mt2.age=9555
>>> mt2.age
9555
>>> mt2.name
'梯阅线条'