Erinnern Sie sich an 2016? Während die Welt mit Pokemon Go und den Olympischen Spielen in Rio beschäftigt war, schrieb ich als College-Student mit großen Augen mein allererstes „Hello, World!“ in Python. Damals hatte ich keine Ahnung, was die Beibehaltung der Wörterbuchreihenfolge bedeutet, geschweige denn, warum die Python-Community über die Aufnahme in die kommende Version 3.6 schwärmte. Wenn ich jetzt als erfahrener Entwickler zurückblicke, ist es erstaunlich zu sehen, wie weit sowohl Python als auch ich gekommen sind.
Von F-Strings in 3.6 über den bahnbrechenden Mustervergleich in 3.10 bis hin zur Free-Thread-Funktion in 3.13 hat Python die Grenzen dessen, was wir mit saubererem, ausdrucksstärkerem Code erreichen können, konsequent erweitert. Es ist, als würde man zusehen, wie sein Lieblingssuperheld mit jedem Film neue Kräfte erhält – nur dass wir statt Netze zu schießen oder einen Hammer zu schwingen, bessere Werkzeuge bekommen, um die wahren Bösewichte zu bekämpfen: Codekomplexität und Ausführlichkeit.
In diesem Artikel starten wir unsere Zeitmaschine und unternehmen eine Reise durch die wichtigsten Funktionen, die in jeder Python-Version von 3.6 bis 3.13 eingeführt wurden. Wir werfen einen Blick auf die wichtigsten Funktionen jeder Version und untersuchen, wie sie die Art und Weise, wie wir Python-Code schreiben, verändert haben. Egal, ob Sie ein erfahrener Pythonist sind, der in Erinnerungen schwelgen möchte, oder ein Neuling, der neugierig auf die Entwicklung der Sprache ist, schnallen Sie sich an – uns erwartet eine spannende Reise durch die Python-Geschichte!
Am Ende dieser Reise sehen Sie sich vielleicht einfach Ihren alten Code an und denken: „Wow, wie konnten wir jemals ohne diese Funktionen leben?“ Lassen Sie uns eintauchen und sehen, wie unser Favorit funktioniert Die Schlange hat sich im Laufe der Jahre gehäutet und ist mit jeder Verwandlung stärker und kraftvoller geworden.
Wenn es eine Funktion gibt, die Python-Entwickler gemeinsam aufatmen ließ, dann sind es F-Strings. Erinnern Sie sich an die Tage der .format()- und %-Formatierung? F-Strings kamen herein, um uns vor den Albträumen der ausführlichen String-Formatierung zu bewahren.
# The old ways name, language, year = "Alice", "Python", 2016 print("{} started learning {} in {}".format(name, language, year)) # .format() print("%s started learning %s in %d" % (name, language, year)) # % formatting # The f-string way print(f"{name} started learning {language} in {year}") # But wait, there's more! F-strings can handle expressions items = ["code", "coffee", "bugs"] print(f"Developer life: {', '.join(items[:-1])} and {items[-1]}") print(f"Hours coding today: {8 * 2}") # Math? No problem! # They even work with method calls message = " python rocks " print(f"Confession: {message.strip().title()}")
Für diejenigen von uns, die mit großen Zahlen zu tun haben, war diese Funktion ein Wendepunkt. Schluss mit dem Zählen von Nullen auf Ihrem Bildschirm!
# The old ways name, language, year = "Alice", "Python", 2016 print("{} started learning {} in {}".format(name, language, year)) # .format() print("%s started learning %s in %d" % (name, language, year)) # % formatting # The f-string way print(f"{name} started learning {language} in {year}") # But wait, there's more! F-strings can handle expressions items = ["code", "coffee", "bugs"] print(f"Developer life: {', '.join(items[:-1])} and {items[-1]}") print(f"Hours coding today: {8 * 2}") # Math? No problem! # They even work with method calls message = " python rocks " print(f"Confession: {message.strip().title()}")
Typhinweise gab es schon früher, aber Python 3.6 machte sie durch variable Annotationen flexibler. Es ermöglichte sauberere Typhinweise und ebnete den Weg für eine bessere statische Analyse.
# Before: Is this a billion or a million? ? old_budget = 1000000000 # After: Crystal clear! ? new_budget = 1_000_000_000 # Works with different number types hex_address = 0xFF_FF_FF_FF # Much easier to read! binary_flag = 0b_1111_0000 # Grouping bits
Bonus-Tipp: Diese Anmerkungen haben keinen Einfluss auf das Laufzeitverhalten – es handelt sich um Hinweise für Entwickler und Tools. Aber sie sorgen dafür, dass die automatische Vervollständigung Ihrer IDE wie von Zauberhand funktioniert! ✨
Erinnern Sie sich noch daran, Klassen mit einer Reihe von __init__-Parametern geschrieben und dann jeden einzelnen mühsam zugewiesen zu haben? Dataclasses vereinfachte die Erstellung von Klassen durch die automatische Generierung von Boilerplate-Code wie __init__, __repr__ und __eq__.
# Before Python 3.6 (still works, but less flexible) def get_user_data(user_id: int) -> dict: pass # Python 3.6 style from typing import Dict, List, Optional # Class attributes with type hints class UserDataAnalyzer: premium_users: List[int] = [] cache: Dict[int, str] = {} last_analyzed: Optional[str] = None def analyze_user(self, user_id: int) -> None: # Some analysis logic here self.last_analyzed = "2024-10-07"
Diese Funktion klingt langweilig, löste aber ein großes Problem: Sie ermöglichte Vorwärtsverweise und eine verbesserte Leistung mit verzögerter Auswertung.
from dataclasses import dataclass from datetime import datetime # Before dataclasses ? class OldBooking: def __init__(self, id, destination, traveler, date, price): self.id = id self.destination = destination self.traveler = traveler self.date = date self.price = price def __repr__(self): return f"Booking({self.id}, {self.destination}, {self.traveler})" def __eq__(self, other): return isinstance(other, OldBooking) and self.id == other.id # After dataclasses ? @dataclass class Booking: id: int destination: str traveler: str date: datetime price: float def total_with_tax(self, tax_rate: float = 0.1) -> float: return self.price * (1 + tax_rate) # Using our dataclass trip = Booking( id=42, destination="Python Island", traveler="Pythonista", date=datetime.now(), price=199.99 ) print(f"Trip cost with tax: ${trip.total_with_tax():.2f}")
Vorbei sind die Zeiten der Eingabe von Import-PDB; pdb.set_trace(). Jetzt können wir einfach einen Breakpoint() setzen und mit unserem Leben weitermachen!
from __future__ import annotations from typing import List class ChessGame: def __init__(self): self.players: List[Player] = [] # This now works! self.board: Board = Board() # This too! def add_player(self, player: Player) -> None: self.players.append(player) def get_winner(self) -> Player | None: # Python 3.10 union type just for fun! # Game logic here return None class Player: def __init__(self, name: str, rating: int): self.name = name self.rating = rating class Board: def __init__(self): self.moves: List[tuple[Player, str]] = []
Debugging-Tipp: Legen Sie die Umgebungsvariable PYTHONBREAKPOINT fest, um das Haltepunktverhalten zu steuern:
def calculate_universe_answer(): numbers = list(range(43)) breakpoint() # Your IDE probably supports this better than pdb! return sum(numbers) - 903 def main(): print("Calculating the answer to life, universe, and everything...") result = calculate_universe_answer() print(f"The answer is: {result}") # When you run this, you'll drop into a debugger at the breakpoint # Try these in the debugger: # - 'numbers' to see the list # - 'len(numbers)' to check its length # - 'n' to go to next line # - 'c' to continue execution
Python 3.7 war vielleicht nicht so auffällig wie 3.6, brachte aber einige ernsthafte Verbesserungen der Lebensqualität. Allein durch Datenklassen konnten weltweit wahrscheinlich Millionen von Tastenanschlägen eingespart werden! Alles, was das Debuggen erleichtert, ist in vergoldeten Pythons sein Gewicht wert.
Die umstrittenste und dennoch leistungsstärkste Ergänzung zu Python. Es ermöglicht Ihnen, Variablen als Teil eines größeren Ausdrucks Werte zuzuweisen.
Mit dem Walross-Operator können Sie zwei Dinge gleichzeitig tun:
# Disable all breakpoints export PYTHONBREAKPOINT=0 # Use a different debugger (like IPython's) export PYTHONBREAKPOINT=IPython.embed
Wenn Sie sagen möchten: „Diese Argumente kommen hierher, es werden keine Fragen gestellt!“. Sie können Argumente angeben, die nach Position und nicht nach Schlüsselwort übergeben werden müssen. Diese Funktion erhöht die Flexibilität des API-Designs und kann wichtige Änderungen in Funktionssignaturen verhindern.
# Consider this code example: while True: user_input = input("Enter something (or 'quit' to exit): ") if user_input == 'quit': break print(f"You entered: {user_input}") # We can simplify above code using walrus operator like this: while (user_input := input("Enter something (or 'quit' to exit): ")) != 'quit': print(f"You entered: {user_input}")
Unterstützung für = innerhalb von F-Strings hinzugefügt, um das Debuggen zu vereinfachen.
def create_character(name, /, health=100, *, special_move): return f"{name}: {health}HP, Special: {special_move}" # These work player1 = create_character("Pythonista", special_move="Code Sprint") player2 = create_character("Bug Slayer", health=120, special_move="Debug Strike") # This fails - name must be positional # player3 = create_character(name="Syntax Error", special_move="Crash Game")
Der Walross-Operator ließ uns prägnanteren Code schreiben (obwohl mit großer Leistung auch große Verantwortung einhergeht!), Nur-Positions-Parameter gaben uns mehr Kontrolle über unsere Funktionsschnittstellen und das F-String-Debugging machte das Drucken-Debuggen tatsächlich angenehm.
Endlich hat uns Python eine saubere Möglichkeit gegeben, Wörterbücher zusammenzuführen! Erinnern Sie sich an die Tage, als wir dict1.update(dict2) schreiben oder {**dict1, **dict2} verwenden mussten? Diese Tage liegen nun hinter uns.
# The old ways name, language, year = "Alice", "Python", 2016 print("{} started learning {} in {}".format(name, language, year)) # .format() print("%s started learning %s in %d" % (name, language, year)) # % formatting # The f-string way print(f"{name} started learning {language} in {year}") # But wait, there's more! F-strings can handle expressions items = ["code", "coffee", "bugs"] print(f"Developer life: {', '.join(items[:-1])} and {items[-1]}") print(f"Hours coding today: {8 * 2}") # Math? No problem! # They even work with method calls message = " python rocks " print(f"Confession: {message.strip().title()}")
Dieser Zusatz machte typing.List, typing.Dict usw. überflüssig und vereinfachte Typanmerkungen.
# Before: Is this a billion or a million? ? old_budget = 1000000000 # After: Crystal clear! ? new_budget = 1_000_000_000 # Works with different number types hex_address = 0xFF_FF_FF_FF # Much easier to read! binary_flag = 0b_1111_0000 # Grouping bits
Diese mögen einfach erscheinen, aber sie sind unglaublich leistungsstark für die Textverarbeitung. Kein umständliches String-Slicing oder replace()-Aufrufe mehr mit fest codierten Längen!
# Before Python 3.6 (still works, but less flexible) def get_user_data(user_id: int) -> dict: pass # Python 3.6 style from typing import Dict, List, Optional # Class attributes with type hints class UserDataAnalyzer: premium_users: List[int] = [] cache: Dict[int, str] = {} last_analyzed: Optional[str] = None def analyze_user(self, user_id: int) -> None: # Some analysis logic here self.last_analyzed = "2024-10-07"
Python 3.10 (veröffentlicht im Oktober 2021) brachte einige wirklich tolle Mustervergleichsfunktionen auf den Tisch.
Switch-Fälle waren im letzten Jahrzehnt so. Der Mustervergleich kam wie ein Schweizer Taschenmesser für Datenstrukturen auf den Markt. Es geht nicht nur darum, Werte abzugleichen; Es geht darum, Daten mit der Eleganz eines Code-Sommeliers zu dekonstruieren.
from dataclasses import dataclass from datetime import datetime # Before dataclasses ? class OldBooking: def __init__(self, id, destination, traveler, date, price): self.id = id self.destination = destination self.traveler = traveler self.date = date self.price = price def __repr__(self): return f"Booking({self.id}, {self.destination}, {self.traveler})" def __eq__(self, other): return isinstance(other, OldBooking) and self.id == other.id # After dataclasses ? @dataclass class Booking: id: int destination: str traveler: str date: datetime price: float def total_with_tax(self, tax_rate: float = 0.1) -> float: return self.price * (1 + tax_rate) # Using our dataclass trip = Booking( id=42, destination="Python Island", traveler="Pythonista", date=datetime.now(), price=199.99 ) print(f"Trip cost with tax: ${trip.total_with_tax():.2f}")
Python 3.10 führte eine saubere Möglichkeit ein, mehrere Kontextmanager mithilfe von Klammern zu verwalten.
from __future__ import annotations from typing import List class ChessGame: def __init__(self): self.players: List[Player] = [] # This now works! self.board: Board = Board() # This too! def add_player(self, player: Player) -> None: self.players.append(player) def get_winner(self) -> Player | None: # Python 3.10 union type just for fun! # Game logic here return None class Player: def __init__(self, name: str, rating: int): self.name = name self.rating = rating class Board: def __init__(self): self.moves: List[tuple[Player, str]] = []
Python entschied, dass „AttributeError“ nicht hilfreich genug war und entschied sich für „Meinten Sie…“-Vorschläge. Es ist, als hätte man einen integrierten Codeprüfer, der tatsächlich helfen möchte, anstatt nur auf Fehler hinzuweisen.
def calculate_universe_answer(): numbers = list(range(43)) breakpoint() # Your IDE probably supports this better than pdb! return sum(numbers) - 903 def main(): print("Calculating the answer to life, universe, and everything...") result = calculate_universe_answer() print(f"The answer is: {result}") # When you run this, you'll drop into a debugger at the breakpoint # Try these in the debugger: # - 'numbers' to see the list # - 'len(numbers)' to check its length # - 'n' to go to next line # - 'c' to continue execution
Unterhaltsame Tatsache: Die Mustervergleichssyntax wurde von Rust und anderen funktionalen Programmiersprachen inspiriert, aber Python hat sie pythonischer gemacht. Wenn Sie Sprachen wie Scala oder Elixir beherrschen, werden Sie sich wie zu Hause fühlen!
Python 3.11 brachte etwas, nach dem wir uns alle gesehnt hatten – erhebliche Geschwindigkeitsverbesserungen! Diese Veröffentlichung war nicht nur schnell; Es war „bis zu 60 % schneller als Python 3.10“ und im Durchschnitt 25 % schneller. Aber das ist noch nicht alles. Lassen Sie mich Ihnen die aufregendsten Funktionen vorstellen, die diese Version zu etwas Besonderem gemacht haben.
Obwohl es sich hierbei nicht um eine Funktion handelt, die Sie im Code „sehen“ können, ist sie eine, die Sie auf jeden Fall spüren werden. Mit Python 3.11 wurde ein spezieller adaptiver Interpreter eingeführt, der die Ausführung Ihres Codes erheblich beschleunigt. Hier ist ein kurzes Beispiel zur Veranschaulichung:
# Disable all breakpoints export PYTHONBREAKPOINT=0 # Use a different debugger (like IPython's) export PYTHONBREAKPOINT=IPython.embed
Die Geschwindigkeitsverbesserung macht sich insbesondere bei CPU-intensiven Aufgaben, Fehlerbehandlung und tief verschachtelten Funktionsaufrufen bemerkbar. Es ist, als ob Python ins Fitnessstudio gegangen wäre und mit mehr Kraft zurückgekommen wäre als je zuvor! ?
Diese Funktion ist ein Lebensretter bei gleichzeitigen Vorgängen, bei denen mehrere Fehler gleichzeitig auftreten können. Anstatt nur eine Ausnahme abzufangen, können wir jetzt mehrere Ausnahmen als Gruppe behandeln!
# The old ways name, language, year = "Alice", "Python", 2016 print("{} started learning {} in {}".format(name, language, year)) # .format() print("%s started learning %s in %d" % (name, language, year)) # % formatting # The f-string way print(f"{name} started learning {language} in {year}") # But wait, there's more! F-strings can handle expressions items = ["code", "coffee", "bugs"] print(f"Developer life: {', '.join(items[:-1])} and {items[-1]}") print(f"Hours coding today: {8 * 2}") # Math? No problem! # They even work with method calls message = " python rocks " print(f"Confession: {message.strip().title()}")
Python 3.11 verbesserte die Entwicklerproduktivität durch eine genauere Lokalisierung von Fehlern. Es ist, als hätte man einen integrierten Debugging-Assistenten!
# Before: Is this a billion or a million? ? old_budget = 1000000000 # After: Crystal clear! ? new_budget = 1_000_000_000 # Works with different number types hex_address = 0xFF_FF_FF_FF # Much easier to read! binary_flag = 0b_1111_0000 # Grouping bits
Diese Fehlermeldungen sind besonders hilfreich, wenn es um komplexe mathematische Operationen oder verschachtelte Methodenaufrufe geht. Kein manuelles Zählen der Klammern mehr!
Python 3.11 war nicht nur ein weiteres inkrementelles Update – es war ein gewaltiger Fortschritt in Bezug auf Leistung und Entwicklererfahrung. Allein die Geschwindigkeitsverbesserungen machen es zu einem überzeugenden Upgrade, aber fügen Sie noch die neuen Ausnahmebehandlungsfunktionen und verbesserten Fehlermeldungen hinzu, und Sie haben eine Veröffentlichung, die den Titel „The Speedster“ wirklich verdient!
Mit Python 3.12 sind F-Strings noch besser geworden! Frühere Versionen hatten einige Einschränkungen – keine Backslashes oder Kommentare in F-Strings und komplexe Ausdrücke erforderten manchmal Problemumgehungen.
# Before Python 3.6 (still works, but less flexible) def get_user_data(user_id: int) -> dict: pass # Python 3.6 style from typing import Dict, List, Optional # Class attributes with type hints class UserDataAnalyzer: premium_users: List[int] = [] cache: Dict[int, str] = {} last_analyzed: Optional[str] = None def analyze_user(self, user_id: int) -> None: # Some analysis logic here self.last_analyzed = "2024-10-07"
Sie müssen TypeVar oder Generic nicht mehr explizit importieren, was den Boilerplate reduziert und die Lesbarkeit des Codes verbessert, ohne die Funktionalität zu beeinträchtigen.
from dataclasses import dataclass from datetime import datetime # Before dataclasses ? class OldBooking: def __init__(self, id, destination, traveler, date, price): self.id = id self.destination = destination self.traveler = traveler self.date = date self.price = price def __repr__(self): return f"Booking({self.id}, {self.destination}, {self.traveler})" def __eq__(self, other): return isinstance(other, OldBooking) and self.id == other.id # After dataclasses ? @dataclass class Booking: id: int destination: str traveler: str date: datetime price: float def total_with_tax(self, tax_rate: float = 0.1) -> float: return self.price * (1 + tax_rate) # Using our dataclass trip = Booking( id=42, destination="Python Island", traveler="Pythonista", date=datetime.now(), price=199.99 ) print(f"Trip cost with tax: ${trip.total_with_tax():.2f}")
Einer der am längsten bestehenden Schwachstellen von Python ist der Global Interpreter Lock (GIL), ein Mechanismus, der es jeweils nur einem Thread ermöglicht, Python-Bytecode auszuführen. Dies hat zu Leistungsengpässen in Multithread-Programmen geführt, insbesondere bei CPU-gebundenen Aufgaben. Allerdings führt Python 3.12 eine wesentliche Verbesserung ein: Per-Interpreter-GIL.
Einfach ausgedrückt verhindert die GIL, dass Python wirklich mehrere Threads gleichzeitig ausführt. Obwohl Threads häufig für E/A-gebundene Vorgänge (wie das Lesen von Dateien oder das Senden von Netzwerkanforderungen) verwendet werden, schränkt die GIL die Vorteile von Multithreading für CPU-intensive Arbeitslasten ein. Dies ist seit langem eine Herausforderung für Python-Entwickler, die die Vorteile von Multi-Core-Prozessoren nutzen müssen.
Mit Python 3.12 verfügen Interpreter jetzt über eine eigene GIL, sodass mehrere Interpreter im selben Prozess parallel ausgeführt werden können, ohne durch eine einzige globale Sperre eingeschränkt zu werden. Dies ist besonders nützlich für die Multi-Core-Verarbeitung. Python 3.12 unterstützt jedoch nur die GIL pro Interpreter über die C-API. Vollständige Python-API-Unterstützung wird in Python 3.13 hinzugefügt.
Mehr über diese Funktion:
Python 3.12 hat möglicherweise nicht die unmittelbaren Auswirkungen auf die Leistung von 3.11, aber seine Verbesserungen an der Ergonomie des Typsystems und den F-String-Fähigkeiten machen es zu einer wichtigen Version für das Schreiben von wartbarem, typsicherem Code. Diese Funktionen sind besonders wertvoll in größeren Projekten, bei denen Codeklarheit und Typsicherheit von entscheidender Bedeutung sind.
Python 3.13 verbessert den Read-Eval-Print-Loop (REPL) und macht ihn intelligenter und benutzerfreundlicher. Jetzt kann REPL mehrere Codezeilen effektiver ausführen, bessere Syntaxvorschläge anzeigen und ein verbessertes Autovervollständigungserlebnis bieten.
Die neue REPL verfügt über die folgenden neuen Funktionen:
Python-Entwickler sind seit Jahren in dem heiklen Tanz um den Global Interpreter Lock (GIL) gefangen, einem Mechanismus, der verhindert, dass mehrere native Threads Python-Bytecodes gleichzeitig ausführen. Obwohl die GIL ihre Vorteile hat, stellt sie auch einen Engpass für Multithread-Anwendungen dar.
Der Free-Threading-Modus in Python 3.13 zielt darauf ab, diese Ketten zu durchbrechen, indem die GIL deaktiviert wird. Dies ermöglicht echte Parallelität in Multithread-Python-Programmen. Im Wesentlichen können Ihre Threads jetzt gleichzeitig ausgeführt werden, wodurch die Multi-Core-Prozessoren optimal genutzt werden. In früheren Versionen zwang die GIL, dass diese Threads einzeln ausgeführt wurden, wodurch die Ausführung effektiv serialisiert wurde.
Sie können die Installationsprogramme für macOS oder Windows herunterladen – sie verfügen über eine Free-Threading-Option, oder Sie können pyenv zum Erstellen und Installieren aus der Quelle verwenden (empfohlen): pyenv install 3.13.0t
Hinweis: Obwohl der Free-Threaded-Modus einen großen Fortschritt in der Entwicklung von Python darstellt, ist es wichtig, seinen experimentellen Status im Auge zu behalten (erwarten Sie einige Fehler). Darüber hinaus kommt es bei Free-Threaded-Builds aufgrund des deaktivierten spezialisierten adaptiven Interpreters (PEP 659) zu einem Leistungseinbruch von 40 % bei Single-Threaded.
Der experimentelle Just-In-Time (JIT)-Compiler markiert einen weiteren wichtigen Meilenstein in der Entwicklung von Python. Der JIT-Compiler funktioniert, indem er Python-Bytecode während der Laufzeit dynamisch in Maschinencode übersetzt. Dies geschieht mithilfe einer Technik namens „Copy-and-Patch“. Dies bedeutet, dass häufig ausgeführte Codepfade im laufenden Betrieb kompiliert werden, was kann theoretisch zu erheblichen Leistungsverbesserungen für kritische Abschnitte Ihres Codes führen kann.
Jetzt seien Sie noch nicht zu aufgeregt. In seiner aktuellen Form ist der JIT-Compiler nicht dazu gedacht, Ihren Code schneller zu machen – er zielt lediglich darauf ab, mit der normalen Python-Leistung Schritt zu halten. Dabei wird dem Prozess jedoch ein zusätzlicher Schritt hinzugefügt, was ziemlich beeindruckend ist. Das Python-Team hat große Pläne für diese kleine Engine und hofft, sie in zukünftigen Versionen auf Vordermann zu bringen, um uns echte Geschwindigkeitssteigerungen zu ermöglichen, ohne den Speicher zu belasten. Im Moment geht es eher darum, das Konzept zu beweisen und den Grundstein für zukünftige Optimierungen zu legen.
Während wir die Veröffentlichung von Python 3.13 feiern, ist eines klar: Bei der Entwicklung von Python geht es nicht nur um das Hinzufügen von Funktionen – es geht darum, das Leben der Entwickler einfacher zu machen, eine Version nach der anderen. Es geht nicht nur darum, Code zu schreiben; Es geht darum, besseren Code zu schreiben, eleganter und mit weniger Kopfschmerzen.
Also, liebe Pythonisten, ruhen wir uns nicht auf unseren Lorbeeren aus. Das Python von heute ist nicht das Python, das wir gestern gelernt haben, und das Python von morgen könnte uns noch einmal überraschen. Erforschen Sie weiter, lernen Sie weiter und erweitern Sie weiterhin die Grenzen des Möglichen mit diesen beiden einfachen Worten: Importieren Sie dies
Dieser Artikel wurde ursprünglich auf meinem persönlichen Blog veröffentlicht.
Das obige ist der detaillierte Inhalt vonPythonic Time Capsule: Wichtige Funktionen aus jeder Version. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!