Heim  >  Artikel  >  Backend-Entwicklung  >  Detaillierte Erläuterung von Generatoren, Iteratoren, dynamisch hinzugefügten Attributen und Methoden in Python

Detaillierte Erläuterung von Generatoren, Iteratoren, dynamisch hinzugefügten Attributen und Methoden in Python

WBOY
WBOYnach vorne
2023-04-21 13:22:081356Durchsuche

1. Generatordefinition

In Python wird der Mechanismus, der während der Schleife berechnet, als Generator bezeichnet Bei großen Datenmengen wird viel Speicher verbraucht.

Zum Beispiel: Wenn Sie nur auf die ersten paar Elemente zugreifen müssen, wird der gesamte nachfolgende Platz verschwendet

Wenn die Listenelemente nach einem bestimmten Algorithmus berechnet werden, können Sie die nachfolgenden Elemente während der Schleife kontinuierlich berechnen, also Sie müssen keine vollständige Liste erstellen und sparen so viel Platz.

3. Methode 1 zum Erstellen eines Generators (Generatorausdruck)

Der Generatorausdruck ist sehr einfach in () zu ändern, um einen Generator (Generator) zu erstellen.

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 Erstellen eines Generators (Generatorfunktion)

1. Generatorfunktion

Wenn eine Funktion das Schlüsselwort yield enthält, ist die Funktion keine gewöhnliche Funktion mehr, die ein Generatorobjekt erstellt

    Generatorfunktion: Verwenden Sie das Schlüsselwort yield, um sofort ein Ergebnis zurückzugeben, zu blockieren und erneut zu beginnen Iterator und läuft weiter zur nächsten Yield-Anweisung, ruft jeden Rückgabewert einzeln ab, bis keine Yield-Anweisung mehr vorhanden ist, und löst schließlich eine StopIteration-Ausnahme aus zurückgegebene Position. In der nächsten Iteration beginnt der Code mit der Ausführung ab der nächsten Anweisung (nicht der nächsten Zeile) von yield
  • send() kann wie next() generieren. Der Generator geht einen Schritt nach unten (stoppt das nächste Mal). es trifft auf Yield), aber send() kann einen Wert übergeben, der als Gesamtergebnis des Yield-Ausdrucks verwendet wird
  • &#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. Zusammenfassung

  • 1. Was ist ein Generator? Der Generator speichert nur eine Reihe von Algorithmen zum Generieren von Werten und lässt nicht zu, dass der Algorithmus jetzt ausgeführt wird. Wenn Sie ihn aufrufen, beginnt er mit der Berechnung einen neuen Wert und geben Sie ihn an Sie zurück
2. Generatorfunktionen
  • Die Generatorfunktion generiert eine Reihe von Ergebnissen. Nachdem ein Wert über das Schlüsselwort yield zurückgegeben wurde, kann er an der Stelle weiterlaufen, an der er beendet wurde, sodass jederzeit eine Reihe von Werten generiert werden kann.

  • Generatoren und Iterationen sind eng miteinander verbunden und verfügen über eine __next__()-Mitgliedsmethode, die entweder das nächste Element der Iteration zurückgibt oder eine Ausnahme zum Beenden der Iteration auslöst.

  • Ein Generator ist ein spezielles Programm, mit dem das iterative Verhalten einer Schleife gesteuert werden kann.

2. Iterator 1. Konzept

Iteration ist eine der leistungsstärksten Funktionen von Python. Es ist eine Möglichkeit, auf die Elemente einer Sammlung zuzugreifen

Ein Iterator ist ein Objekt, das sich die durchquerte Position merken kann

Das Iteratorobjekt beginnt mit dem Zugriff vom ersten Element der Menge, bis auf alle Elemente zugegriffen wurde
  • Iteratoren können nur vorwärts und nicht rückwärts gehen

  • Iteratoren haben zwei grundlegende Methoden:

    iter()
  • und
  • netx()

2. Der Unterschied zwischen iterierbaren Objekten und Iteratoren

    Ein Objekt Das die Iter-Methode implementiert, heißt „Iterable object Ieratable“
  • Ein Objekt, das die nächste Methode implementiert und iterierbar ist, wird „Iterator“ genannt. Iterator bedeutet: implementiert die Iter-Methode und next Das Objekt der Methode ist der Iterator
  • !

    Generatoren sind alle
  • Iterator-Objekte, aber
  • list

    ,

    dict
  • ,
  • str

    Obwohl sie alle Iterable (iterierbare Objekte) sind, sind sie keine Iteratoren

    &#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 Der
    Iterator
  • Das Objekt stellt einen

    Datenstrom

    dar. Diese Daten können als geordnete Sequenz betrachtet werden, aber wir können die Länge der Sequenz nicht im Voraus kennen. Wir können die nächsten Daten nur bei Bedarf kontinuierlich über die Funktion
  • next() berechnen, sodass die Berechnung von
  • Iterator

    verzögert ist . Es wird nur berechnet, wenn die nächsten Daten zurückgegeben werden müssen.

  • Der Generator muss also ein Iterator sein. 3. Die Essenz der for-Schleife Die Methode __iter__()
gibt ein spezielles Iteratorobjekt zurück, das die Methode
__next__()

implementiert und den Abschluss der Iteration durch die StopIteration-Ausnahme identifiziert

  • __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
    """

    Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung von Generatoren, Iteratoren, dynamisch hinzugefügten Attributen und Methoden in Python. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

    Stellungnahme:
    Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen