>  기사  >  백엔드 개발  >  Python의 생성기, 반복기, 동적으로 추가된 속성 및 메소드에 대한 자세한 설명

Python의 생성기, 반복기, 동적으로 추가된 속성 및 메소드에 대한 자세한 설명

WBOY
WBOY앞으로
2023-04-21 13:22:081356검색

1. Generator

1. Generator 정의

Python에서는 루프를 실행하는 동안 계산하는 메커니즘을 Generator라고 합니다. Generator

2. 목록의 모든 데이터는 메모리에 있습니다. 데이터 양이 많으면 메모리도 많이 소모됩니다.

예를 들어 처음 몇 개의 요소에만 액세스하면 이후의 모든 공간이 낭비됩니다.

목록 요소가 특정 알고리즘에 따라 계산되면 루프 중에 후속 요소를 계속해서 계산할 수 있으므로 전체 목록을 만들 필요가 없으므로 많은 공간이 절약됩니다.

3. 생성기 생성 방법 1(생성기 표현식)

생성기 표현식은 매우 간단합니다. 생성기(생성기)를 생성하려면 목록 이해의 []를 ()로 변경하면 됩니다.

L = [x * x for x in range(10)]  #推导式
print(L)
g = (x * x for x in range(10)) #加成括号就是生成器
print(g)
#<generator object <genexpr> at 0x1022ef630>
&#39;&#39;&#39;L是一个list,而g则是一个 generator&#39;&#39;&#39;

4. 생성기 생성(생성기 함수)

1. 생성기 함수

    함수에 Yield 키워드가 포함된 경우 해당 함수를 호출하면 생성기 개체가 생성됩니다.
  • 생성기 함수: 한 번에 결과를 반환하고 차단하고 다시 시작하려면 키워드 Yield를 사용하세요
  • 2. 생성기 함수의 작동 방식
    생성기 함수는 반복자를 반환하고 for 루프는 이에 대해 지속적으로 __next__() 함수를 호출합니다. 반복자를 실행하고 다음 항복 문으로 계속 실행하여 항복 문이 없을 때까지 한 번에 하나씩 각 반환 값을 얻고 마침내 StopIteration 예외를 트리거합니다.
  • yield는 반환 시 값을 반환하고 다음 반복에서 코드는 next()와 마찬가지로 다음 명령문(다음 줄 아님)에서 실행을 시작합니다. 생성기는 다음 번에 중지됩니다. Yield가 발생하지만 send()는 항복 표현식의 전체 결과로 사용되는 값을 전달할 수 있습니다.
    &#39;&#39;&#39;
    如果一个函数中包含 yield 关键字,那么这个函数就不再是一个普通函数,
    调用函数就是创建了一个生成器(generator)对象
    生成器函数:其实就是利用关键字 yield 一次性返回一个结果,阻塞,重新开始
    原理
    1. 函数有了yield之后,调用它,就会生成一个生成器
    2. 下次从下一个语句执行,切记不是下一行(tmp = yield i)
    3. return在生成器中代表生成器种植,直接报错:StopIeratation
    4. next方法作用:唤醒并继续执行
    &#39;&#39;&#39;
    def test():
        print("start")
        i = 0
        while i<3:
            &#39;&#39;&#39;yield i #第一次执行,此处挂起;同时将i的值返回到i
                       #第二次执行,从挂起的地方往下执行&#39;&#39;&#39;
            temp = yield i #下次迭代时,代码从`yield`的下一条语句(不是下一行)开始执行
            print(f"i:{i}")
            i += 1
        print("end")
        return "done"
    if __name__ == &#39;__main__&#39;:
        a = test()
        print(type(a))
        print(a.__next__())
        print(a.__next__())
        print(a.__next__())
        print(a.__next__())# 抛出异常:StopIteration
    &#39;&#39;&#39;
    <class &#39;generator&#39;>
    start
    0
    temp:None
    1
    temp:None
    2
    temp:None
    end
    Traceback (most recent call last):
     in <module>
        print(a.__next__())# 抛出异常:StopIteration
    StopIteration: done
    &#39;&#39;&#39;
  • 5. 요약

    1. 생성기는 무엇입니까
  • 생성기는 값을 생성하는 알고리즘 집합만 저장하고 알고리즘이 지금 실행을 시작하도록 하지 않지만, 호출하면 언제부터 계산이 시작되나요? 새로운 가치를 돌려드립니다

    2. 생성기 기능

생성기 기능은 일련의 결과를 생성합니다. Yield 키워드를 통해 값을 반환한 후, 종료된 위치부터 계속 실행될 수 있으므로 언제든지 일련의 값이 생성될 수 있습니다.

Generator와 반복은 밀접하게 관련되어 있습니다. Iterator에는 반복의 다음 항목을 반환하거나 예외를 발생시켜 반복을 종료하는 __next__() 멤버 메서드가 있습니다.

제너레이터는 루프의 반복 동작을 제어하는 ​​데 사용할 수 있는 특수 프로그램입니다.

2. 반복자
1. 개념
  • 반복은 Python의 가장 강력한 기능 중 하나입니다. 컬렉션의 요소에 액세스하는 방법입니다
  • 반복자는 순회 위치를 기억할 수 있는 객체입니다
  • 반복자 객체는 모든 요소에 액세스할 때까지 집합의 첫 번째 요소부터 액세스하기 시작합니다.

Iterator는 앞으로만 갈 수 있고 뒤로는 갈 수 없습니다.

  • Iterator에는

    iter()

  • netx()
  • 2의 두 가지 기본 메서드가 있습니다. 2. 반복 가능한 개체와 반복자의 차이점

  • iter 메소드를 구현하는 객체를 "Iterable 객체 Ieratable"이라고 합니다

  • next 메소드를 구현하고 반복 가능한 객체를 "iterator"라고 합니다. Iterator는 iter 메소드를 구현하고 next를 의미합니다. 메소드의 객체는 반복자

    !
  • Generator는 모두
Iterator

객체이지만

list
    ,
  • dict

    ,

    str
  • 모두
  • Iterable

    (반복 가능한 객체)이지만 Iterator는 아닙니다

  • &#39;&#39;&#39;
    send的作用是唤醒并继续执行,发送一个信息到生成器内部
    &#39;&#39;&#39;
    def foo():
        print("start")
        i = 0
        while i < 2:
            temp = yield i
            print(f"temp:{temp}")
            i += 1
        print("end")
     
    g = foo()
    print(next(g))  #等同g.__next__(),next是内置函数
    print("*"*20)
    print(g.send(100))
    print(next(g))
    # for a in g:#g所返回的值是yield处的i
    #     print(a)
    &#39;&#39;&#39;
    start
    0
    ********************
    temp:100
    1
    temp:None
    end
    Traceback (most recent call last):
        print(next(g))
    StopIteration
    &#39;&#39;&#39;
    &#39;&#39;&#39;
    生成器一定是迭代器
    可迭代对象不一定是迭代器,使用iter([])封装后可转为迭代器
    &#39;&#39;&#39;
    from collections.abc import Iterator
    from collections.abc import Iterable
    a = isinstance([], Iterator) #list、dict、str虽然是Iterable(可迭代对象),却不是Iterator(迭代器)
    print(a)
    a = isinstance([], Iterable) #可迭代对象
    print(a)
    """
    执行结果:
    False
    True
    """

Python 반복자 객체는 데이터 스트림 을 나타냅니다. 이 데이터는 순서가 지정된 시퀀스로 간주될 수 있지만 시퀀스의 길이를 미리 알 수는 없습니다. next() 함수를 통해 요청 시 다음 데이터만 연속적으로 계산할 수 있으므로 Iterator 계산이 게으릅니다. . 다음 데이터를 반환해야 하는 경우에만 계산됩니다. 따라서 생성기는 반복자여야 합니다.

3. for 루프Python의 생성기, 반복기, 동적으로 추가된 속성 및 메소드에 대한 자세한 설명

&#39;&#39;&#39;list、dict、str 等 Iterable 变成 Iterator,可以使用 iter() 函数:&#39;&#39;&#39;
b = isinstance(iter([]), Iterator)
print(b)
b = isinstance(iter(&#39;花非人陌&#39;), Iterator)
print(b)
 
"""
执行结果:
True
True
"""

4. 반복자 만들기

클래스를 반복자로 사용하려면 클래스 __iter__() __next__()

에 두 가지 메서드를 구현해야 합니다. __iter__()

메소드는

__next__()
메소드를 구현하는 특수 반복자 객체를 반환하고 StopIteration 예외를 통해 반복 완료를 식별합니다

  • __next__() 方法会返回下一个迭代器对象

  • #创建一个依次返回10,20,30,...这样数字的迭代器
    class MyNumbers:
        def __iter__(self):
            self.num = 10
            return self
     
        def __next__(self):
            if self.num < 40:
                x = self.num
                self.num += 10
                return x
            else:
                raise StopIteration
     
    myclass = MyNumbers()
    myiter = iter(myclass)
    print(next(myiter))
    print(next(myiter))
    print(next(myiter))
    print(next(myiter))
    """
    执行结果:
    10
    20
    30
    Traceback (most recent call last):
        raise StopIteration
    StopIteration
    """
    """
    程序解析:
    在这段代码中,MyNumbers 类定义了一个迭代器。该迭代器的作用是生成一系列数字,从 10 开始,每次增加 10,直到 40,然后停止。
    在程序中,通过 iter(myclass) 方法获取 MyNumbers 类的迭代器对象 myiter,然后调用 next(myiter) 方法获取下一个数字。
    在第一次调用 next(myiter) 方法时,迭代器会执行 __next__() 方法,返回 self.num 的值 10,然后将 self.num 的值增加 10,变为 20。
    在第二次、第三次调用 next(myiter) 方法时,迭代器会再次执行 __next__() 方法,返回 20 和 30,然后将 self.num 的值分别增加 10,变为 30 和 40。
    在第四次调用 next(myiter) 方法时,迭代器再次执行 __next__() 方法,发现 self.num 的值已经大于等于 40,于是抛出 StopIteration 异常,表示迭代已经结束。
    """

    三、动态添加属性和方法

    1、动态编程语言定义

    指在运行时可以改变其结构的语言:例如新的函数、对象、甚至代码可以被引进,

    已有的函数可以被删除或是其他结构上的变化

    2、运行过程中给对象添加属性和方法

    #coding=utf-8
    import types
    class Person():
        def __init__(self, name, age):
            self.name = name
            self.age = age
     
    p1 = Person("zhangsan", 20)
    p2 = Person("lisi", 18)
    #动态给对象添加属性和方法
    p1.score = 100
    print(p1.score) #加给p1的只能p1用,对象的也是一样
     
    #动态给对象添加方法
    def run(self):
        print(f"{self.name}, running...")
    p1.run = types.MethodType(run, p1)
    #而types.MethodType(run,p1)则是告诉解释器,self指的就是p1
    p1.run()
    """
    执行结果:
    100
    zhangsan, running...
    """

    3、给类动态添加静态方法以及类方法

    #encoding=utf-8
    class Person():
        __slots__ = {"name", "age"}
        def __init__(self, name, age):
            self.name = name
            self.age = age
     
    @staticmethod
    def staticfunc():
        print("--- static method ---")
     
    Person.staticfunc = staticfunc
    Person.staticfunc()
    Person.score = 1000 #动态给对象静态方法
    print(Person.score)
     
    @classmethod
    def clsfunc(cls):
        print(&#39;--- cls method ---&#39;)
    Person.clsfunc = clsfunc    #动态增加类方法
    Person.clsfunc()

    四、限制动态添加

    1、slots

    1. __slots__的作用
    • __slots__ 对动态添加成员变量、成员方法有限制。对动态添加类属性、类方法没有限制

    • __slots__ 只对本类有限制,不限制子类

    2. 对动态添加成员变量、成员方法有限制
    &#39;&#39;&#39;
    MyClass 类使用 __slots__ 属性限制了实例对象的属性,只允许动态添加 x 属性。
    因此,obj.x = 1 可以成功,但是 obj.y = 2 会抛出 AttributeError 异常
    &#39;&#39;&#39;
    class MyClass:
        __slots__ = [&#39;x&#39;]
     
    obj = MyClass()
    obj.x = 1  # 可以动态添加 x 属性
    obj.y = 2  # 报错,__slots__ 限制了不能动态添加 y 属性
    """
    执行结果:
    AttributeError: &#39;MyClass&#39; object has no attribute &#39;y&#39;
    """
    3. 对动态添加类属性、类方法没有限制
    class MyClass:
        __slots__ = [&#39;x&#39;]
        classattr = 1
     
        @classmethod
        def myclassmethod(cls):
            print("class method")
     
     
    MyClass.newclassattr = 2  # 可以动态添加类属性
    print(MyClass.newclassattr)
    MyClass.mynewclassmethod = lambda cls: print("new class method")  # 可以动态添加类方法
    MyClass.mynewclassmethod(MyClass)   #传递类本身作为参数
    obj = MyClass()
    obj.x  = 3    # 可以动态添加实例属性
    print(obj.x)  # 可以动态添加 x 属性
    """
    执行结果:
    2
    new class method
    3
    """

    위 내용은 Python의 생성기, 반복기, 동적으로 추가된 속성 및 메소드에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

    성명:
    이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제