• python运算符重载之构造函数和迭代器


    1 python运算符重载之构造函数和迭代器

    python运算符重载是在类方法中拦截内置操作-当类的实例使用内置操作时,pytho自动调用对应方法,并且返回操作结果。

    NO#描述
    1拦截运算运算符重载拦截内置操作,比如打印、函数调用、点号运算、表达式运算等
    2类似内置重载运算符让类实例的行为类似内置操作
    3特定名称运算符重载通过定义特定名称的类方法类实现
    4双下划线重载的方法名前后都有双下划线

    1.1 常见运算符重载

    NO方法内置操作描述
    1init构造函数c=MyClass()
    2del析构函数对象回收
    3add运算符+如果没有__iadd__,x+y,x+=y
    4or运算符|如果没有_ior__,x|y,x|=y
    5repr,str打印print(x)、repr(x)、str(x)
    6call函数调用x(*args,**kargs)
    7getattr点号运算x.attr
    8setattr属性赋值x.attr=value
    9delattr删除属性del x.attr
    10getattribute属性获取x.attr
    11getitem索引分片运算x[key],x[m:n]
    12setitem索引分片赋值x[key]=value,x[m:n]=序列
    13delitem索引分片删除del[key],del[m:n]
    14len长度len(x)
    15bool布尔测试bool(x)
    16ltgtlegeeqne关系运算符xy,x<=y,x>=y,x==y,x!=y
    17radd右侧加法Other+x
    18iadd增强加法x+=y
    19iternext迭代环境I=iter(X),next(I),for循环
    20contains成员关系item in x
    21index整数值hex(x),bin(x),oct(x),o(x)
    22enterexit环境管理with obj as var:
    23getset描述符属性x.attr,x.attr=value,dle x.attr
    24new创建在__init__之前创建对象

    1.2 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__
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    1.3 sub

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    1.4 getitem__和__setitem

    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=' ')
    012 线 34 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62

    1.5 iter__和__next

    python迭代环境先调用__iter__()方法,不存在时再调用__getitem__()方法进行索引操作。

    iter()方法返回迭代对象,迭代对象循环调用__next__()方法,直到发生StopIteration异常。

    迭代环境循环调用__getitem__()方法,直到发生IndexError异常。

    迭代器对象:具有__next__方法的对象;

    可迭代对象:具有__iter__方法的对象;

    可迭代对象调用__iter__方法,返回迭代器对象,再调用__next__方法;

    1.5.1 单迭代器对象

    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 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65

    1.5.2 多迭代器对象

    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
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
  • 相关阅读:
    艾美捷内毒素纯化树脂基本参数和原理说明
    QT DAY6
    make: /bin/nvcc: Command not found 解决找不到nvcc
    金蝶云星空与旺店通·企业奇门对接集成盘盈单查询打通创建盘点单
    数字信号处理FFT快速傅立叶变换MATLAB实现——实例
    windows 驱动与内核调试 学习
    计算机网络——网络层数据交换方式、IP数据报、IPv4地址、重要协议、IPv6
    不重新安装Anaconda找回不见的Anaconda Prompt
    vue项目中实际构建echarts拓扑关系图业务
    网络安全笔记1——Internet协议的安全性
  • 原文地址:https://blog.csdn.net/sinat_34735632/article/details/134519930