• Python笔记,面向对象(11)遍历操作与描述器


    遍历操作

    怎样让自己创建的对象可以使用for in进行遍历?

    实现_ _ getitem _ _方法

    class Person:
        def __init__(self):
            self.result = 1
    
        def __getitem__(self, item):
            self.result += 1
            if self.result >= 6:
                raise StopIteration("停止遍历")  #raise抛出异常, StopIteration停止遍历
            return self.result
        pass
    
    p = Person()
    
    for i in p:
        print(i)
        
        
    2
    3
    4
    5
        
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    实现_ _ iter _ _方法
    _ _ lter _ _方法的优先级比 _ _ getitem _ _ 方法的优先级要高

    class Person:
        def __init__(self):
            self.result = 1
        def __iter__(self):
            print("iter")
            return iter([1,2,3,4,5,6])   #遍历的就是方法里面的迭代器对象
        pass
    
    p = Person()
    
    for i in p:
        print(i)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    怎样让自己创建的对象可以使用next函数进行访问?

    class Person:
        def __init__(self):
            self.result = 1
    
        def __iter__(self):
            print("iter")
            return self
    
        def __next__(self):
            self.result += 1
            if self.result >= 6:
                raise StopIteration("停止遍历")
            return self.result
        pass
    
    p = Person()
    
    for i in p:
        print(i)
    
    #lter()通过调用__ iter__ 返回一个迭代对象
    #内部执行机制,当我们使用forin去访问遍历一个对象的时候,
    #首先会使用iterator这个函数针对这个p对象计算出它里面的一个迭代器,
    #而这个迭代器获取方法本质就是调用这个对象的方法来获取,
    #拿到这个迭代器之后,使用next函数来针对迭代器来获取下一个数据,
    #知道获取完毕,抛出异常为止。
    
    • 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

    迭代器的复用

    class Person:
        def __init__(self):
            self.age = 1
    
        def __iter__(self):   #迭代器必须实现iter和next方法
            return self
    
        def __next__(self):
            self.age += 1
            if self.age >= 6:
                raise  StopIteration("STOP")
    
            return self.age
    
    p = Person()
    for i in p:
        print(i)
    
    
    import collections    #判断p是不是迭代器
    print(isinstance(p, collections.Iterator))
    
    
    #迭代器一定可以通过next函数进行访问,但是能通过next函数的不一定是迭代器
    
    
    
    • 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

    可迭代对象->实现__iter__方法即可;迭代器->同时实现__iter__和__next__方法

    描述器

    概念

    可以描述一个属性的对象,把多种描述的方法封装到一个对象中,这个对象就是一个描述器,一般而言,描述器是一个包含了描述器协议中的方法的属性值。 这些方法有 [__get__()]get), [__set__()]set) 和 [__delete__()]object.delete)。 如果为某个属性定义了这些方法中的任意一个,它就可以被称为 [descriptor]

    • 对象
    • 属性的操作:增,改,删,查
    • 描述

    定义

    定义方式一:property

    class Person:
        def __init__(self):
            self.__age = 10
    
        @property
        def age(self):
            return self.__age
    
        @age.setter
        def age(self, value):
            if value < 0:
                value = 0
            self.__age = value
        
        @age.deleter
        def age(self):
            del self.__age
    
        # age = property(age, set_age, del_age)
    
    p = Person()
    print(p.age)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    定义方式二:

    class Age:
        def __get__(self, instance, owner):
            print("get")
    
        def __set__(self, instance, value):
            print("set")
    
        def __delete__(self, instance):
            print("del")
    
    class Person:
        age = Age()
    
    
    p = Person()
    p.age = 18
    print(p.age)
    del p.age
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    调用细节

    • 定义一个描述器,一般通过实例来进行操纵描述器,不通过类

    • 不能顺利转化的场景:

      ​ 新式类可以,经典类不可以

    在这里插入图片描述

  • 相关阅读:
    NewStarCTF 2023 公开赛道 WEEK2|Crypto
    Linux进程间通信(二)
    斐波那契数列问题
    ubuntu20.04挂载拓展盘保姆级流程
    Flask初探之WSGI
    【CAN信号解析】使用python-can/cantools解析CAN数据
    typescript72-已有的类型声明文件(第三方库的类型文件)
    [产品管理-2]:产品经理的职责、在企业中的位置与定位
    Linux线程互斥
    离线地图开发-含源代码(免费)
  • 原文地址:https://blog.csdn.net/weixin_49750432/article/details/126004045