[100 Tage Python-Kenntnisse] Tag 24: Detaillierte Erklärung und Beispiele von Python-Iteratoren, -Generatoren und -Dekoratoren

 Inhaltsverzeichnis

 Spaltenführer 

1 Übersicht über Iteratoren, Generatoren und Dekoratoren

1.1 Übersicht

1.2 Anwendungsszenarien

2 Syntax und Beispiele

2.1 Iteratoren

2.2 Generator

2.3 Dekorateure

3 umfassende Anwendungsfälle


Spaltenführer 

Adresse des Kolumnenabonnements: https://blog.csdn.net/qq_35831906/category_12375510.html


1 Übersicht über Iteratoren, Generatoren und Dekoratoren

1.1 Übersicht

  1. Iteratoren (Iteratoren): Ein Iterator ist ein Objekt, das das Iterationsprotokoll implementiert und die Elemente im Container durchlaufen kann. Ein Iterator muss zwei Methoden enthalten __iter__(): und . Die Methode gibt das Iteratorobjekt selbst zurück, die Methode gibt das nächste Element im Container zurück. Eine Ausnahme sollte ausgelöst werden, wenn die Elemente im Container durchlaufen wurden .__next__()__iter__()__next__()__next__()StopIteration

  2. Generatoren: Ein Generator ist eine besondere Art von Iterator, der es uns ermöglicht, Iteratoren präziser zu definieren. Generatoren verwenden yielddas Schlüsselwort, um den nächsten Wert zu ermitteln, anstatt returnein Ergebnis zurückzugeben. Eine Generatorfunktion yieldpausiert jedes Mal, wenn sie aufgerufen wird, und setzt die Ausführung bei der nächsten Iteration an der Stelle fort, an der sie aufgehört hat. Solche Funktionen machen Generatorfunktionen kompakter und effizienter.

  3. Dekoratoren: Dekoratoren sind Funktionen höherer Ordnung, mit denen das Verhalten anderer Funktionen geändert werden kann. Ein Dekorateur nimmt eine Funktion als Eingabe und gibt eine neue Funktion zurück, wobei er normalerweise die ursprüngliche Funktion umschließt, sodass Funktionen hinzugefügt werden können, ohne den ursprünglichen Funktionscode zu ändern. Dekoratoren können verwendet werden, um vor und nach der Funktionsausführung zusätzliche Logik hinzuzufügen, z. B. Protokollierung, Berechtigungsüberprüfung, Leistungsanalyse usw.

        Diese Konzepte sind in Python sehr wichtig und bieten viele praktische Möglichkeiten, Daten zu bearbeiten, Code zu optimieren und Code wiederzuverwenden. Iteratoren und Generatoren machen die Verarbeitung großer Datenmengen effizienter, während Dekoratoren den Code modularer und einfacher zu warten machen. Durch die kluge Anwendung dieser Konzepte können Sie eleganteren und leistungsfähigeren Python-Code schreiben.

1.2 Anwendungsszenarien

        Iteratoren, Generatoren und Dekoratoren sind weit verbreitete Python-Programmierwerkzeuge in verschiedenen Programmierszenarien. Im Folgenden finden Sie gängige Programmierszenarien für sie:

  1. Programmierszenarien für Iteratoren :

    • Durchlaufen von Datensätzen: Iteratoren ermöglichen Speichereinsparungen beim Durchlaufen großer Datensätze, da sie bei Bedarf Daten einzeln abrufen, anstatt den gesamten Datensatz auf einmal in den Speicher zu laden.
    • Dateiverarbeitung: Verwenden Sie bei großen Dateien Iteratoren, um Daten Zeile für Zeile zu lesen und zu verarbeiten, ohne die gesamte Datei auf einmal in den Speicher einlesen zu müssen.
    • Benutzerdefinierter Container: Durch die Implementierung des Iteratorprotokolls können wir benutzerdefinierte Containerobjekte wie Bäume, Diagramme usw. erstellen, sodass wir die for-Schleife von Python verwenden können, um die Elemente im Container zu durchlaufen.
  2. Das Programmierszenario des Generators :

    • Umgang mit großen Datensätzen: Generatoren eignen sich hervorragend für die Arbeit mit großen Datensätzen, da sie Daten bei Bedarf generieren und vermeiden, dass alle Daten auf einmal in den Speicher geladen werden.
    • Unendliche Folge: Der Generator kann Folgen unbegrenzter Länge erzeugen, wie z. B. eine Fibonacci-Folge, eine Primzahlenfolge usw.
    • Verzögerte Berechnung: Die Verwendung von Generatoren ermöglicht verzögerte Berechnungen, bei denen Daten nur dann generiert werden, wenn sie benötigt werden, was in einigen Fällen die Leistung verbessern kann.
  3. Programmierszenarien für Dekorateure :

    • Protokollierung: Dekoratoren können verwendet werden, um Protokollierungsfunktionen zu Funktionen hinzuzufügen und Funktionsaufrufinformationen, Parameter und Ausführungszeit aufzuzeichnen.
    • Leistungsanalyse: Mithilfe von Dekoratoren können wir die Ausführungszeit von Funktionen zur Leistungsanalyse und -optimierung messen.
    • Berechtigungsüberprüfung: Dekoratoren können zur Berechtigungsüberprüfung von Funktionen verwendet werden, um sicherzustellen, dass nur Benutzer mit bestimmten Berechtigungen Funktionen ausführen können.
    • Cache-Ergebnisse: Dekoratoren können verwendet werden, um die Ergebnisse von Funktionen zwischenzuspeichern, um wiederholte Berechnungen zu vermeiden und die Ausführungseffizienz von Funktionen zu verbessern.

Umfangreiche Anwendungsszenarien:

  • Verwenden Sie Generatoren zur Verarbeitung großer Datensätze, kombiniert mit Dekoratoren zur Protokollierung und Leistung der Datenverarbeitung.
  • Verwenden Sie Iteratoren, um große Dateien zu durchlaufen, und kombinieren Sie Dekoratoren, um die Berechtigungsüberprüfung zu implementieren und die Ergebnisse der Dateiverarbeitung zwischenzuspeichern.
  • Verwenden Sie Generatoren, um unendliche Sequenzen zu generieren, z. B. die Generierung von Fibonacci-Zahlen, und kombinieren Sie Dekoratoren, um die Berechnungszeit und die Ergebnisse der Sequenzen aufzuzeichnen.

        Zusammenfassung: Iteratoren, Generatoren und Dekoratoren haben alle ein breites Spektrum an Anwendungsszenarien in der Python-Programmierung. Sie machen Code effizienter, flexibler und wartbarer, insbesondere bei großen Datenmengen und komplexen Aufgaben.


2 Syntax und Beispiele

2.1 Iteratoren

        In Python sind Iteratoren (Iteratoren) ein Mechanismus zum Durchlaufen von Elementen in einem Container. Es bietet eine einfache und einheitliche Möglichkeit, auf jedes Element in einer Sammlung zuzugreifen, ohne die interne Struktur der Sammlung zu kennen. Iteratoren sind beim Umgang mit großen Datensätzen sehr nützlich, da sie nicht den gesamten Datensatz auf einmal in den Speicher laden müssen, sondern die Daten bei Bedarf einzeln abrufen, wodurch Speicher gespart und die Leistung verbessert wird.

        Viele in Python integrierte Datentypen unterstützen die Iteration, z. B. Listen, Tupel, Wörterbücher, Mengen usw. Die Kernidee eines Iterators besteht darin, die Traversierung durch __iter__()die Methoden und __next__()zu implementieren . Wenn wir aufrufen iter(iterable), wird ein Iteratorobjekt zurückgegeben, mit dem wir dann next(iterator)das nächste Element im Container abrufen können, bis alle Elemente durchlaufen wurden. An diesem Punkt StopIterationwird eine Ausnahme ausgelöst.

Hier ist ein einfaches Iterator-Beispiel:

class MyIterator:
    def __init__(self, data):
        self.data = data
        self.index = 0

    def __iter__(self):
        return self

    def __next__(self):
        if self.index >= len(self.data):
            raise StopIteration
        value = self.data[self.index]
        self.index += 1
        return value

# 使用自定义迭代器遍历列表
my_list = [1, 2, 3, 4, 5]
my_iterator = MyIterator(my_list)
for item in my_iterator:
    print(item)

Ausgang:

1
2
3
4
5

Im obigen Beispiel haben wir eine MyIteratorIteratorklasse mit dem Namen definiert und darin __iter__()die Methoden und implementiert. __next__()Dann iterieren wir mit einem benutzerdefinierten Iterator über eine Liste my_list.

Es ist erwähnenswert, dass Python integrierte Funktionen iter()und bereitstellt next(), sodass wir in der eigentlichen Programmierung selten selbst Iteratorklassen definieren müssen. Iterierbare Objekte können direkt mit iter()und iteriert werden.next()

my_list = [1, 2, 3, 4, 5]
my_iterator = iter(my_list)
while True:
    try:
        item = next(my_iterator)
        print(item)
    except StopIteration:
        break

Die Ausgabe ist die gleiche wie zuvor

1
2
3
4
5

Hier verwenden wir  die Funktion iter()„and“ next(), um die Liste manuell zu durchlaufen und StopIterationdas Durchlaufen zu stoppen, wenn eine Ausnahme auftritt.

Zusammenfassung: Iteratoren sind eine sehr leistungsstarke und häufig verwendete Funktion in Python, die das Durchlaufen von Daten einfach und effizient macht. Unabhängig davon, ob benutzerdefinierte Iteratorklassen oder die integrierten Funktionen „ iter()and“ verwendet werden next(), sind Iteratoren bei der Arbeit mit Datensätzen sehr nützlich.


2.2 Generator

        In Python sind Generatoren eine spezielle Art von Iteratoren, die das yieldSchlüsselwort verwenden, um Werte zu erzeugen, anstatt returnein Ergebnis zurückzugeben. Die Ausführung einer Generatorfunktion yieldwird bei jedem Aufruf von pausiert und bei der nächsten Iteration an der Stelle fortgesetzt, an der sie aufgehört hat. Diese Funktion macht Generatorfunktionen kompakter, effizienter und speichereffizienter.

        Der Vorteil eines Generators besteht darin, dass er nicht alle Daten auf einmal in den Speicher laden muss, sondern Daten bei Bedarf generiert. Dies ist beim Umgang mit großen Datenmengen sehr nützlich, da es den Speicherbedarf reduziert und die Programmleistung verbessert.

Hier ist ein einfaches Generatorbeispiel:

def countdown(n):
    while n > 0:
        yield n
        n -= 1

# 使用生成器遍历倒计时
for i in countdown(5):
    print(i)

Ausgang

5
4
3
2
1

         Im obigen Beispiel haben wir eine countdownGeneratorfunktion namens definiert. Es verwendet das Schlüsselwort in jeder Schleife, yieldum einen Countdown-Wert zu generieren, und bei der nächsten Iteration wird die Ausführung dort fortgesetzt, wo sie aufgehört hat. Daher wird bei jeder Iteration ein Countdown-Wert ausgegeben.

        Es ist erwähnenswert, dass Generatorfunktionen keinen Wert zurückgeben, sondern einen Iterator generieren. Wir können ein Generatorobjekt erhalten, indem wir die Generatorfunktion aufrufen und es zum Iterieren verwenden. Der Generator löst eine Ausnahme aus, wenn alle Werte generiert wurden StopIteration.

        Neben yieldder Definition von Generatoren über unterstützt Python auch die Verwendung von Generatorausdrücken zum schnellen Erstellen von Generatoren. Generatorausdrücke ähneln Listenverständnissen, verwenden jedoch Klammern anstelle von eckigen Klammern.

Beispiel:

# 使用生成器表达式生成一个包含 1 到 5 的生成器
my_generator = (x for x in range(1, 6))

# 遍历生成器并输出值
for item in my_generator:
    print(item)

Ausgang

1
2
3
4
5

 Generatoren sind leistungsstarke und flexible Werkzeuge in Python. Durch die Verwendung yielddes Schlüsselworts zum Definieren einer Generatorfunktion oder eines Generatorausdrucks können wir Speicher sparen, die Leistung verbessern und den Code bei der Verarbeitung großer Datenmengen prägnanter gestalten.


2.3 Dekorateure

        Dekoratoren sind eine erweiterte Funktion in Python, die es uns ermöglicht, einer Funktion zusätzliche Funktionalität oder Verhalten hinzuzufügen, ohne den ursprünglichen Funktionscode zu ändern. Ein Dekorator ist im Wesentlichen eine Funktion, die eine andere Funktion als Argument verwendet und eine neue Funktion zurückgibt. Auf diese Weise können wir vor, nach dem Aufruf der Funktion oder während der Ausführung der Funktion eine gemeinsame Logik einfügen.

        Die Dekorator-Syntax verwendet @die Notation, bevor der Dekorator auf die Zielfunktion angewendet wird.

Schauen wir uns ein einfaches Beispiel an:

# 定义一个简单的修饰器函数
def my_decorator(func):
    def wrapper():
        print("Something is happening before the function is called.")
        func()
        print("Something is happening after the function is called.")
    return wrapper

# 使用修饰器来装饰函数
@my_decorator
def say_hello():
    print("Hello!")

# 调用被装饰的函数
say_hello()

Ausgang:

Something is happening before the function is called.
Hello!
Something is happening after the function is called.

 Im obigen Beispiel haben wir eine my_decoratorDekoratorfunktion namens definiert, die eine funcFunktion als Argument akzeptiert und eine neue Funktion zurückgibt wrapper. Innerhalb wrapperder Funktion fügen wir zusätzliche Logik hinzu, die funceinige Informationen vor und nach dem Aufruf der Zielfunktion ausgibt.

Anschließend wenden wir den Dekorator mithilfe @my_decoratorder Syntax auf die Funktion an , die Folgendes bewirkt:my_decoratorsay_hello

say_hello = my_decorator(say_hello)

Auf diese Weise say_hello()rufen wir beim Aufrufen der Funktion tatsächlich die geänderte wrapperFunktion auf, sodass vor und nach dem Drucken von „Hallo!“ zusätzliche Logik ausgeführt wird.

Zusätzlich zu den oben genannten Beispielen können Dekorateure auch Parameter verwenden, um sie flexibler zu machen. Zum Beispiel:

def repeat(num_times):
    def my_decorator(func):
        def wrapper(*args, **kwargs):
            for _ in range(num_times):
                result = func(*args, **kwargs)
            return result
        return wrapper
    return my_decorator

@repeat(num_times=3)
def say_hello(name):
    print(f"Hello, {name}!")

say_hello("John")

 Ausgang:

Hello, John!
Hello, John!
Hello, John!

        In diesem Beispiel definieren wir einen Dekorator mit einem Parameter repeat, der angibt, wie oft die Funktion ausgeführt werden soll. Mithilfe @repeat(num_times=3)der Syntax wenden wir repeatden Dekorator auf say_hellodie Funktion an und geben an, dass die Funktion dreimal ausgeführt wird.

        Zusammenfassung: Dekoratoren sind ein leistungsstarkes und flexibles Programmiertool in Python, das Code modularer und lesbarer macht und das Hinzufügen allgemeiner Logik ermöglicht, ohne den ursprünglichen Funktionscode zu ändern. Durch die Verwendung von Dekoratoren können wir allgemeine Funktionen wie Protokollierung, Leistungsanalyse, Berechtigungsüberprüfung usw. einfach implementieren und so den Code eleganter und wartbarer machen.


3 umfassende Anwendungsfälle

        Angenommen, Sie haben eine Liste mit einer großen Anzahl von Ganzzahlen und müssen nun jede darin enthaltene Ganzzahl quadrieren und vor und nach jeder Operation protokollieren, einschließlich der Ausführungszeit der Funktion.

Es ist erforderlich, ein Programm zu implementieren, das die folgenden Funktionen umfasst:

  1. Definiert eine Generatorfunktion square_generator(data), die eine Liste von Ganzzahlen dataals Argument verwendet und einen Generator zurückgibt. Der Generator liefert nacheinander den quadrierten Wert jeder Ganzzahl in der Liste.
  2. Definiert eine Dekoratorfunktion log_decorator(func), die eine Funktion funcals Argument akzeptiert und eine neue Funktion zurückgibt wrapper. Innerhalb wrapperder Funktion wird funcdie Ausführungszeit der Funktion aufgezeichnet und das Ausführungszeitprotokoll ausgegeben.
  3. Wendet den Dekorator log_decoratorauf eine Generatorfunktion an square_generator, um eine neue dekorierte Generatorfunktion zu erstellen log_square_generator.
  4. Erstellen Sie eine Liste mit einer großen Anzahl von Ganzzahlen data_list, rufen Sie die dekorierte Generatorfunktion auf log_square_generator(data_list)und beobachten Sie die Protokollausgabe der Laufzeit.

Letztendlich sind Programme in der Lage, große Datenmengen zu verarbeiten und Ausführungszeiten automatisch aufzuzeichnen, wodurch Code effizienter und wartbarer wird.

Code wie folgt anzeigen:

import time

# 生成器函数:平方生成器
def square_generator(data):
    for item in data:
        yield item ** 2

# 修饰器函数:日志记录
def log_decorator(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"Function {func.__name__} executed in {end_time - start_time:.6f} seconds.")
        return result
    return wrapper

# 经过修饰的生成器函数:带有日志记录的平方生成器
@log_decorator
def log_square_generator(data):
    for item in data:
        yield item ** 2

# 创建一个大型数据集的列表
data_list = list(range(1, 1000000001))

# 使用经过修饰的生成器处理数据,并观察日志输出
for square in log_square_generator(data_list):
    pass

Die Ausgabe ist wie folgt:

       Im obigen Fall haben wir zunächst square_generatordie Generatorfunktion definiert, die das Quadrat jedes Elements in der Liste zurückgibt. Anschließend definieren wir log_decoratordie Dekoratorfunktion, die die Ausführungszeit und Parameter der Funktion aufzeichnet.

        Als Nächstes wenden wir den Dekorator an square_generatorund erstellen so eine neue dekorierte Generatorfunktion log_square_generator, die vor und nach der Auswertung protokolliert.

     Schließlich erstellen wir eine Liste eines großen Datensatzes und verwenden eine dekorierte Generatorfunktion, log_square_generatorum die Daten zu verarbeiten und die Protokollausgabe zu beobachten. Wenn Sie den Code ausführen, wird die verstrichene Zeit des Generators protokolliert.

        Dieses Beispiel in voller Länge zeigt, wie Sie Iteratoren, Generatoren und Dekoratoren nutzen, um große Datenmengen zu verarbeiten und generische Protokollierungsfunktionen hinzuzufügen, um Ihren Code effizienter, flexibler und wartbarer zu machen.

Ich denke du magst

Origin blog.csdn.net/qq_35831906/article/details/131983269
Empfohlen
Rangfolge