Inhaltsverzeichnis
1 Übersicht über Iteratoren, Generatoren und Dekoratoren
Spaltenführer
Adresse des Kolumnenabonnements: https://blog.csdn.net/qq_35831906/category_12375510.html
1 Übersicht über Iteratoren, Generatoren und Dekoratoren
1.1 Übersicht
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
Generatoren: Ein Generator ist eine besondere Art von Iterator, der es uns ermöglicht, Iteratoren präziser zu definieren. Generatoren verwenden
yield
das Schlüsselwort, um den nächsten Wert zu ermitteln, anstattreturn
ein Ergebnis zurückzugeben. Eine Generatorfunktionyield
pausiert 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.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:
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.
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.
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 StopIteration
wird 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 MyIterator
Iteratorklasse 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 StopIteration
das 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 yield
Schlüsselwort verwenden, um Werte zu erzeugen, anstatt return
ein Ergebnis zurückzugeben. Die Ausführung einer Generatorfunktion yield
wird 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 countdown
Generatorfunktion namens definiert. Es verwendet das Schlüsselwort in jeder Schleife, yield
um 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 yield
der 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 yield
des 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_decorator
Dekoratorfunktion namens definiert, die eine func
Funktion als Argument akzeptiert und eine neue Funktion zurückgibt wrapper
. Innerhalb wrapper
der Funktion fügen wir zusätzliche Logik hinzu, die func
einige Informationen vor und nach dem Aufruf der Zielfunktion ausgibt.
Anschließend wenden wir den Dekorator mithilfe @my_decorator
der Syntax auf die Funktion an , die Folgendes bewirkt:my_decorator
say_hello
say_hello = my_decorator(say_hello)
Auf diese Weise say_hello()
rufen wir beim Aufrufen der Funktion tatsächlich die geänderte wrapper
Funktion 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 repeat
den Dekorator auf say_hello
die 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:
- Definiert eine Generatorfunktion
square_generator(data)
, die eine Liste von Ganzzahlendata
als Argument verwendet und einen Generator zurückgibt. Der Generator liefert nacheinander den quadrierten Wert jeder Ganzzahl in der Liste. - Definiert eine Dekoratorfunktion
log_decorator(func)
, die eine Funktionfunc
als Argument akzeptiert und eine neue Funktion zurückgibtwrapper
. Innerhalbwrapper
der Funktion wirdfunc
die Ausführungszeit der Funktion aufgezeichnet und das Ausführungszeitprotokoll ausgegeben. - Wendet den Dekorator
log_decorator
auf eine Generatorfunktion ansquare_generator
, um eine neue dekorierte Generatorfunktion zu erstellenlog_square_generator
. - Erstellen Sie eine Liste mit einer großen Anzahl von Ganzzahlen
data_list
, rufen Sie die dekorierte Generatorfunktion auflog_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_generator
die Generatorfunktion definiert, die das Quadrat jedes Elements in der Liste zurückgibt. Anschließend definieren wirlog_decorator
die Dekoratorfunktion, die die Ausführungszeit und Parameter der Funktion aufzeichnet.Als Nächstes wenden wir den Dekorator an
square_generator
und erstellen so eine neue dekorierte Generatorfunktionlog_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_generator
um 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.