Python魔法之__getitem__

Python魔法之__getitem__

上篇文章探讨了__call__魔法方法,这里探讨__getitem__的奇妙之处。

Python中的对象分为可迭代对象与不可迭代对象,那么什么是可迭代对象呢?

可以这样简单地说,可以使用for i in obj进行遍历的对象均为可迭代对象,不能用for i in obj进行遍历的就是不可迭代对象。

因此range(n)、list、tuple、str、dict等均为可迭代对象,而int、float与一般的函数对象、类对象等是不可迭代对象。

可迭代对象之所以可迭代,就是因为内部实现了__iter____getitem__魔法方法

  1. 如果不定义__getitem__

    class MyList:
        def __init__(self,len:int):
            self.list=[i for i in range(len)]
            self.length=len
    
        def __repr__(self)->str:
            return f"MyList({self.length}):{self.list}"
    
    x=MyList(10)
    x[7]
    

    结果报错,显示MyList不可以通过下标访问:

    Traceback (most recent call last):
      File "d:\Github-Projects\Crack_Detection_Daily\He\env.py", line 14, in <module>
        x[7]
    TypeError: 'MyList' object is not subscriptable
    
  2. 定义__getitem__

    from numpy import iterable
    class MyList:
        def __init__(self, len: int):
            self.list = [i for i in range(len)]
            self.length = len
    
        def __getitem__(self, index: int) -> int:
            return self.list[index]
    
        def __repr__(self) -> str:
            return f"MyList({self.length}):{self.list}"
    
    x = MyList(10)
    print(x[7])
    print(x.__getitem__(7))
    print(iterable(x))
    print(x[7] is x.__getitem__(7))
    for i in x:
        print(i,end=' ')
    

    注:numpy.iterable(x)可以判断x是否为可迭代对象

    输出为:

    7
    7
    True
    True
    0 1 2 3 4 5 6 7 8 9
    

    由此可见,通过x[7] 等价于x.__getitem__(7),即定义了__getitem__方法就能使该元素变为可迭代对象,可以通过下标进行访问。

    不仅如此,一般来说只要是可迭代对象,均有x.__getitem__(y) <==> x[y],字典也不例外:

    dic = {
        'hjd': 'yyds',
        'zyy': 'goddess'
    }
    
    print(dic.__getitem__('hjd'))
    print(dic['hjd'])
    print(dic['hjd'] is dic.__getitem__('hjd'))
    
    

    结果:

    yyds
    yyds
    True
    

你可能感兴趣的:(Python,python,numpy,开发语言)