python运算符重载是在类方法中拦截内置操作-当类的实例使用内置操作时,pytho自动调用对应方法,并且返回操作结果。
NO | # | 描述 |
---|---|---|
1 | 拦截运算 | 运算符重载拦截内置操作,比如打印、函数调用、点号运算、表达式运算等 |
2 | 类似内置 | 重载运算符让类实例的行为类似内置操作 |
3 | 特定名称 | 运算符重载通过定义特定名称的类方法类实现 |
4 | 双下划线 | 重载的方法名前后都有双下划线 |
NO | 方法 | 内置操作 | 描述 |
---|---|---|---|
1 | init | 构造函数 | c=MyClass() |
2 | del | 析构函数 | 对象回收 |
3 | add | 运算符+ | 如果没有__iadd__,x+y,x+=y |
4 | or | 运算符| | 如果没有_ior__,x|y,x|=y |
5 | repr,str | 打印 | print(x)、repr(x)、str(x) |
6 | call | 函数调用 | x(*args,**kargs) |
7 | getattr | 点号运算 | x.attr |
8 | setattr | 属性赋值 | x.attr=value |
9 | delattr | 删除属性 | del x.attr |
10 | getattribute | 属性获取 | x.attr |
11 | getitem | 索引分片运算 | x[key],x[m:n] |
12 | setitem | 索引分片赋值 | x[key]=value,x[m:n]=序列 |
13 | delitem | 索引分片删除 | del[key],del[m:n] |
14 | len | 长度 | len(x) |
15 | bool | 布尔测试 | bool(x) |
16 | lt,gt,le,ge,eq,ne | 关系运算符 | x |
17 | radd | 右侧加法 | Other+x |
18 | iadd | 增强加法 | x+=y |
19 | iter,next | 迭代环境 | I=iter(X),next(I),for循环 |
20 | contains | 成员关系 | item in x |
21 | index | 整数值 | hex(x),bin(x),oct(x),o(x) |
22 | enter,exit | 环境管理 | with obj as var: |
23 | get,set | 描述符属性 | x.attr,x.attr=value,dle x.attr |
24 | new | 创建 | 在__init__之前创建对象 |
python类调用小括号()创建实例时,会自动调用实例的构造函数__init__()。
>>> class A:
def __init__(self):
print('A.__init__')
>>> class B(A):
def __init__(self):
print('B.__init__')
>>> class C(A):pass
>>> a=A()
A.__init__
# 子类和父类有init,自动调用子类init
>>> b=B()
B.__init__
# 子类无init,自动调用父类init
>>> c=C()
A.__init__
python实例使用减法-表达式,会自动调用实例的__sub__()方法。
>>> class MyNumber:
def __init__(self,begin):
self.data=begin
def __sub__(self,other):# 拦截减法(-)表达式
return MyNumber(self.data-other)
>>> n1=MyNumber(5)
>>> n2=n1-3
>>> n2.data
2
python实例使用索引和分片获取值时,会自动调用实例的__getitem__()方法;
设置值时,会自动调用__setitem方法;
迭代环境会自动调用__getitem__()方法;
>>> class MyIndex:
def __getitem__(self,index):# []索引获取值时调用getitem
return index*2
>>> mi=MyIndex()
>>> mi[2]
4
>>> for i in range(5):
print(mi[i],end=' ')
0 2 4 6 8
>>> class MySlice:
data=[9,7,5,2,6,8]
def __getitem__(self,index):# [:]分片获取值时调用getitem
print('索引:',index)
return self.data[index]
>>> ms=MySlice()
>>> ms[0]
索引: 0
9
>>> ms[1]
索引: 1
7
>>> ms[-1]
索引: -1
8
>>> ms[3:6]
索引: slice(3, 6, None)
[2, 6, 8]
>>> ms[1:]
索引: slice(1, None, None)
[7, 5, 2, 6, 8]
>>> ms[:-1]
索引: slice(None, -1, None)
[9, 7, 5, 2, 6]
>>> ms[::2]
索引: slice(None, None, 2)
[9, 5, 6]
>>> class MySetitem:
def __init__(self):
self.changed={}
def __setitem__(self,key,value):# 索引[]设置值时调用setitem
self.changed[key]=value
def __getitem__(self,key):
return self.changed[key]
>>> ms=MySetitem()
>>> ms['s']='梯阅线条'
>>> ms['s']
'梯阅线条'
>>> class MyStep:
def __getitem__(self,i):# for循环迭代时调用getitem
print(i,end = ' ')
return self.data[i]
>>> ms=MyStep()
>>> ms.data='梯阅线条'
>>> ms[0]
0 '梯'
>>> for item in ms:
print(item,end=' ')
0 梯 1 阅 2 线 3 条 4
python迭代环境先调用__iter__()方法,不存在时再调用__getitem__()方法进行索引操作。
iter()方法返回迭代对象,迭代对象循环调用__next__()方法,直到发生StopIteration异常。
迭代环境循环调用__getitem__()方法,直到发生IndexError异常。
迭代器对象:具有__next__方法的对象;
可迭代对象:具有__iter__方法的对象;
可迭代对象调用__iter__方法,返回迭代器对象,再调用__next__方法;
iter()方法返回实例对象本身,为单迭代器对象,生成器函数和表达式、map、zip等;
>>> class MyIter:
def __init__(self,start,stop):
self.value=start-1
self.stop=stop
# 可迭代迭代对象拥有__iter__方法,返回迭代器对象
def __iter__(self):
return self
def __next__(self):# 迭代器对象拥有__next__方法
if self.value==self.stop:
raise StopIteration
self.value+=1
return self.value*2
>>> for i in MyIter(1,5):
# for迭代环境循环调用迭代器对象的next方法
print(i,end=' ')
2 4 6 8 10
>>> mi=MyIter(1,5)
>>> i=iter(mi)#等效于mi.__iter__()
>>> i
<__main__.MyIter object at 0x01269A50>
# 等效于 i.__next__()
>>> next(i)
2
>>> next(i)
4
>>> next(i)
6
>>> next(i)
8
>>> next(i)
10
>>> next(i)
Traceback (most recent call last):
File "" , line 1, in <module>
next(i)
File "" , line 9, in __next__
raise StopIteration
StopIteration
>>> [i for i in MyIter(1,5)]
[2, 4, 6, 8, 10]
>>> [i for i in MyIter(1,5)]
[2, 4, 6, 8, 10]
# mi的__iter__()返回实例本身,为单次迭代器
# 类似的有生成器函数和表达式、map、zip
>>> mi=MyIter(1,5)
>>> [i for i in mi]
[2, 4, 6, 8, 10]
>>> [i for i in mi]
[]
>>> mi=MyIter(1,5)
>>> for x in mi:
for y in mi:
print(x+y,end=' ')
6 8 10 12
>>> def mygenerate(start,stop):
for i in range(start,stop+1):
yield i*2
>>> for i in mygenerate(1,5):
print(i,end=' ')
2 4 6 8 10
iter()方法返回新迭代器对象,为多迭代器对象,比如range、列表等;
class MySkipIterator:
def __init__(self,wrapped):
self.wrapped=wrapped
self.offset=0
# 迭代器对象拥有__next__方法
def __next__(self):
print('__next__')# 证明 __next__ 被调用
if self.offset>=len(self.wrapped):
print('StopIteration')
raise StopIteration
else:
item=self.wrapped[self.offset]
self.offset+=2
return item
class MySkipObject:
def __init__(self,wrapped):
self.wrapped=wrapped
# 可迭代迭代对象拥有__iter__方法,
# 返回拥有__next__方法的迭代器对象
def __iter__(self):
# __iter__返回新的迭代器对象,为多个迭代器对象
# 类似的有range、列表等
print('__iter__')# 证明 __iter__ 被调用
return MySkipIterator(self.wrapped)
if __name__ == '__main__':
s1='abcdef'
mso=MySkipObject(s1)
i=iter(mso)
print(next(i),next(i),next(i))
print('================')
#for循环先调用iter生成迭代器,再一直调用next方法只到报错
for x in mso:
print(x,end=' ')
print('================')
for x in mso:
for y in mso:
print(x+y,end=' ')
'''
C:\Users\Administrator\Desktop>python "新文件 1.py"
__iter__
__next__
__next__
__next__
a c e
================
__iter__
__next__
a __next__
c __next__
e __next__
StopIteration
================
__iter__
__next__
__iter__
__next__
aa __next__
ac __next__
ae __next__
StopIteration
__next__
__iter__
__next__
ca __next__
cc __next__
ce __next__
StopIteration
__next__
__iter__
__next__
ea __next__
ec __next__
ee __next__
StopIteration
__next__
StopIteration
'''