„Dies ist die erste Version von Python, die standardmäßig das 64-Bit-Installationsprogramm unter Windows verwendet. Das Installationsprogramm verbietet jetzt auch aktiv die Installation unter Windows 7. "
„Dies ist die erste Version von Python, die standardmäßig das 64-Bit-Installationsprogramm unter Windows verwendet. Das Installationsprogramm verhindert jetzt auch die Installation unter Windows 7. "
Ich habe die Python 3.9-Versionshinweise und die dazugehörigen Diskussionen gelesen. Basierend auf den Informationen wollte ich einen umfassenden Leitfaden schreiben, damit jeder einen Eindruck von den Funktionen und seiner detaillierten Arbeit bekommen kann.
UPD :
Übergang zu stabilen jährlichen Freisetzungszyklen, siehe PEP 602
alec_kalinin
„Jede neue Version von Python wird jetzt im Oktober erscheinen. Python 3.10 wird im Oktober 2021 veröffentlicht, Python 3.11 im Oktober 2022. Buckfix wird alle zwei Monate veröffentlicht. Das sind großartige Neuigkeiten für mich. Jetzt können wir klar planen, die Python-Umgebung zu aktualisieren. "
PEP 584
In diesem PEP wird vorgeschlagen, die Operatoren merge ( | ) und update ( | = ) zur integrierten dict-Klasse hinzuzufügen .
Zusammenführen: |
>>> a = {'milk': 'prostokvashino', 'heese': 'cheddar'}
>>> b = {'milk': 1, 'heese': 2, 'bread': 3}
>> > | b
{'milk': 1, 'heese': 2, 'bread': 3}
>>> b | a
{'milk': 'prostokvashino', 'heese': 'cheddar', 'bread': 3}
So aktualisieren Sie: | =
>>> a | = b
>>> a
{'milk': 1, 'heese': 2, 'bread': 3}
Die wichtigste Regel, an die Sie sich erinnern sollten, ist, dass bei Schlüsselkonflikten der Wert ganz rechts erhalten bleibt.
Natürlich werden viele Pythonisten eine Frage haben, warum dies notwendig ist, wenn es bereits eine Option gibt, die jedem bekannt ist
{**d1, **d2}
Diese Frage wurde im PEP selbst beantwortet:
Das Auspacken von Wörterbüchern sieht hässlich aus und ist nicht leicht zu erkennen. Nur wenige werden erraten können, was dies bedeutet, wenn sie es zum ersten Mal sehen.
Wie Guido sagte :
Ich entschuldige mich für PEP 448 , aber selbst wenn Sie ** d in einem einfacheren Kontext kennen und einen typischen Python-Benutzer fragen, wie man zwei Diktate zu einem neuen kombiniert, bezweifle ich, dass viele Leute an {** d1, ** denken würden d2}. Ich weiß, dass ich es selbst vergessen habe, als dieser Thread begann!
Auch {** d1, ** d2} funktioniert nicht für Diktat-Unterklassen wie defaultdict
PEP 585
Generische Typhinweise in Standardsammlungen.
Generisch ist ein Typ, der parametrisiert werden kann, eine Art Container. Wird auch als parametrischer Typ oder generischer Typ bezeichnet.
Diese Version unterstützt die universelle Syntax in allen Standardkollektionen, die derzeit im Typing-Modul verfügbar sind. Wir können verwenden Liste oder dict - Typen als generische Typen statt mit typing.List oder typing.Dict .
Es war:
from typing import List
a: List[str] = list()
def read_files(files: List[str]) -> None:
pass
Wurden:
a: list[str] = list()
def read_files(files: list[str]) -> None:
pass
Vollständige Liste der Typen
tuple
list
dict
set
frozenset
type
collections.deque
collections.defaultdict
collections.OrderedDict
collections.Counter
collections.ChainMap
collections.abc.Awaitable
collections.abc.Coroutine
collections.abc.AsyncIterable
collections.abc.AsyncIterator
collections.abc.AsyncGenerator
collections.abc.Iterable
collections.abc.Iterator
collections.abc.Generator
collections.abc.Reversible
collections.abc.Container
collections.abc.Collection
collections.abc.Callable
collections.abc.Set # typing.AbstractSet
collections.abc.MutableSet
collections.abc.Mapping
collections.abc.MutableMapping
collections.abc.Sequence
collections.abc.MutableSequence
collections.abc.ByteString
collections.abc.MappingView
collections.abc.KeysView
collections.abc.ItemsView
collections.abc.ValuesView
contextlib.AbstractContextManager # typing.ContextManager
contextlib.AbstractAsyncContextManager # typing.AsyncContextManager
re.Pattern # typing.Pattern, typing.re.Pattern
re.Match # typing.Match, typing.re.Match
list
dict
set
frozenset
type
collections.deque
collections.defaultdict
collections.OrderedDict
collections.Counter
collections.ChainMap
collections.abc.Awaitable
collections.abc.Coroutine
collections.abc.AsyncIterable
collections.abc.AsyncIterator
collections.abc.AsyncGenerator
collections.abc.Iterable
collections.abc.Iterator
collections.abc.Generator
collections.abc.Reversible
collections.abc.Container
collections.abc.Collection
collections.abc.Callable
collections.abc.Set # typing.AbstractSet
collections.abc.MutableSet
collections.abc.Mapping
collections.abc.MutableMapping
collections.abc.Sequence
collections.abc.MutableSequence
collections.abc.ByteString
collections.abc.MappingView
collections.abc.KeysView
collections.abc.ItemsView
collections.abc.ValuesView
contextlib.AbstractContextManager # typing.ContextManager
contextlib.AbstractAsyncContextManager # typing.AsyncContextManager
re.Pattern # typing.Pattern, typing.re.Pattern
re.Match # typing.Match, typing.re.Match
PEP 615
Unterstützung der IANA-Zeitzonendatenbank in der Standardbibliothek.
IANA-Zeitzonen werden häufig als tz- oder Zoneninformationen bezeichnet. Es gibt eine große Anzahl von IANA-Zeitzonen mit unterschiedlichen Suchpfaden zum Festlegen der IANA-Zeitzone für ein Datums- und Zeitobjekt. Beispielsweise können wir den Namen des Suchpfads als Kontinent / Stadt an ein Datum / Uhrzeit-Objekt übergeben, um dessen tzinfo festzulegen.
dt: datetime = datetime(2000, 01, 25, 01, tzinfo=ZoneInfo("Europe/London"))
Wenn wir den falschen Schlüssel übergeben, wird eine Ausnahme ausgelöst
zoneinfo.ZoneInfoNotFoundError
PEP 616
Neue Zeichenfolgenfunktionen zum Entfernen von Präfix und Suffix.
Dem str- Objekt wurden zwei neue Funktionen hinzugefügt.
- Die erste Funktion entfernt das Präfix.
str.removeprefix(prefix) - Die zweite Funktion entfernt das Suffix.
str.removesuffix(suffix)
>>> 'hello_world'.removeprefix ('hello_')
world
>>> 'hello_world'.removesuffix ('_world')
hello
PEP 617
Python 3.9 schlägt vor, den aktuellen LL (1) -basierten Python-Parser durch einen neuen PEG-basierten Parser zu ersetzen, der eine hohe Leistung und Stabilität bietet.
Der aktuelle CPython-Parser basiert auf LL (1). Anschließend basiert die Grammatik auf LL (1), wodurch sie mit einem LL (1) -Parser analysiert werden kann. Der LL (1) -Parser arbeitet von oben nach unten. Außerdem werden die Eingabedaten von links nach rechts analysiert. Die aktuelle Grammatik ist kontextfreie Grammatik, daher wird der Kontext der Token nicht berücksichtigt.
Python 3.9 schlägt vor, es durch einen neuen PEG-basierten Parser zu ersetzen, was bedeutet, dass die aktuellen Einschränkungen der LL (1) -Grammatik von Python aufgehoben werden. Darüber hinaus wurden Korrekturen am aktuellen Parser vorgenommen und eine Reihe von Hacks hinzugefügt, die entfernt werden. Dies reduziert auf lange Sicht die Wartungskosten.
Während LL (1) -Parser und -Grammatiken beispielsweise einfach zu implementieren sind, verhindern Einschränkungen, dass sie gemeinsame Konstrukte auf natürliche Weise für den Sprachdesigner und -leser ausdrücken. Der Parser sieht nur ein Token nach vorne, um zwischen Möglichkeiten zu unterscheiden.
issue30966
Möglichkeit, simultane Futures zu stornieren . Concurrent.futures.Executor.shutdown () wurde
ein neuer Parameter cancel_futures hinzugefügt . Dieser Parameter enthält alle ausstehenden Futures, die noch nicht gestartet wurden. Vor Version 3.9 wartete der Prozess auf den Abschluss, bevor der Executor beendet wurde. Ein neuer Parameter cancel_futures hat wurde hinzugefügt ThreadPoolExecutor und ProcessPoolExecutor . Es funktioniert, wenn der Parameterwert True ist. Alle ausstehenden Futures werden abgebrochen, wenn die Funktion shutdown () aufgerufen wird . Beim Herunterfahren ()
ausgeführt wird, prüft der Interpreter, ob der Executor Müll gesammelt hat. Wenn es sich noch im Speicher befindet, werden alle ausstehenden Elemente abgerufen und die Futures abgebrochen.
issue30966
In dieser Version wurden einige Verbesserungen an der Asyncio-Bibliothek und der Multiprocessing-Bibliothek vorgenommen.
Zum Beispiel,
- Der Parameter reuse_address asyncio.loop.create_datagram_endpoint () wird aufgrund erheblicher Sicherheitsprobleme nicht mehr unterstützt.
- Neue Coroutinen, shutdown_default_executor () und asyncio.to_thread () Coroutinen hinzugefügt . Ein neuer Aufruf von asyncio.to_thread () wird verwendet, um E / A-bezogene Funktionen in einem separaten Thread auszuführen, um ein Blockieren der Ereignisschleife zu vermeiden.
Für die Verbesserungen der Multiprocessing-Bibliothek wurde der Multiprocessing.SimpleQueue- Klasse eine neue close () -Methode hinzugefügt .
Diese Methode schließt die Warteschlange explizit. Dies stellt sicher, dass die Warteschlange geschlossen ist und nicht länger als erwartet bleibt. Es ist wichtig zu beachten, dass die Methoden get (), put (), empty () nach dem Schließen der Warteschlange nicht mehr aufgerufen werden können.
issue37444
Fehler beim Importieren von Paketen behoben.
Das Hauptproblem beim Importieren von Python-Bibliotheken vor der Version 3.9 war das inkonsistente Importverhalten in Python, wenn relative Importe von seinem Top-Level-Paket übergeben wurden.
Builtins .__ import __ () hat ValueError ausgelöst, während importlib .__ import __ () ImportError ausgelöst hat.
Jetzt ist es korrigiert . __Import __ () löst jetzt ImportError anstelle von ValueError aus.
issue40286
Erzeugung zufälliger Bytes.
Eine weitere Funktion, die in Version 3.9 hinzugefügt wurde, ist random.Random.randbytes () . Es kann verwendet werden, um zufällige Bytes zu erzeugen.
Wir können Zufallszahlen generieren, aber was ist, wenn wir zufällige Bytes generieren müssen? Vor Version 3.9 mussten Entwickler kreativ sein, um zufällige Bytes zu generieren. Obwohl wir os.getrandom () , os.urandom () oder Secrets.token_bytes () verwenden können, können wir keine pseudozufälligen Muster generieren.
Um beispielsweise sicherzustellen, dass Zufallszahlen mit dem erwarteten Verhalten generiert werden und der Prozess reproduziert wird, verwenden wir normalerweise Startwert mit dem random.Random-Modul.
Als Ergebnis wurde die Methode random.Random.randbytes () eingeführt . Es werden zufällige Bytes generiert.
issue28029
Korrektur der String-Ersetzungsfunktion.
Das Prinzip der Ersetzungsfunktion besteht darin, dass für ein bestimmtes maximales Argument zum Ersetzen eines Vorkommens der Zeichensatz aus der Zeichenfolge durch den neuen Zeichensatz ersetzt wird.
Um das Problem weiter zu erklären, hatte die Ersetzungsfunktion vor Version 3.9 ein inkonsistentes Verhalten:
Man würde erwarten, Blog zu sehen
"" .replace ("", "blog", 1)
>>> ''
Man würde erwarten, | zu sehen
"" .replace ("", "|", 1)
>>> ''
"" .replace ("", "prefix")
>>> 'prefix'
Ausgabe 39648, Ausgabe 39479, Ausgabe 39288, Ausgabe 39310
Änderungen im Modul "Mathematik".
Gibt das am wenigsten verbreitete Vielfache ganzzahliger Argumente zurück:
>>> import math
>>> math.lcm(48,72,108)
432
Gibt den größten gemeinsamen Teiler ganzzahliger Argumente zurück. In der früheren Version wurden nur zwei Argumente unterstützt. Unterstützung für eine beliebige Anzahl von Argumenten hinzugefügt:
>>> import math
>>> math.gcd(9,12,21)
3
Berechnet die Gleitkommazahl , die " x " in Richtung " y " am nächsten liegt .
>>> math.nextafter(2, -1)
1.9999999999999998
Diese Methode gibt den Wert des niedrigstwertigen Bits der Gleitkommazahl x zurück.
>>> 1 - math.ulp(1)
0.9999999999999998
>>> math.nextafter(1, -1) + math.ulp(1)
1.0
Ausgabe 38870
Die unparse-Methode wurde dem ast-Modul hinzugefügt.
Mit der neuen Methode kann eine Codezeile erstellt und anschließend ausgeführt werden.
>>> import ast
>>> parsed = ast.parse('from sys import platform; print(platform)')
>>> unparsed_str = ast.unparse(parsed)
>>> print(unparsed_str)
from sys import platform
print(platform)
>>> exec(unparsed_str)
win32
Ausgabe 39507, Ausgabe 39509
Hinzufügen neuer Codes zu http.HTTPStatus.
" Sparen Sie 418! "
418 IM_A_TEAPOT
103 EARLY_HINTS
425 TOO_EARLY
UPD :
PEP 614
Lockerung der grammatikalischen Einschränkungen für Dekorateure.
Es war:
buttons = [QPushButton(f'Button {i}') for i in range(10)]
button_0 = buttons[0]
@button_0.clicked.connect
def spam():
...
button_1 = buttons[1]
@button_1.clicked.connect
def eggs():
...
Jetzt können Sie unnötige Zuordnungen entfernen und direkt anrufen:
buttons = [QPushButton(f'Button {i}') for i in range(10)]
@buttons[0].clicked.connect
def spam():
...
@buttons[1].clicked.connect
def eggs():
...
„Das Tupel muss in Klammern stehen.“
Dies basiert auf Guidos Vision im selben Brief. Zitat:
Aber ich werde keine Kommas zulassen. Dem kann ich nicht zustimmen
@f, g def pooh(): ...
Dies kann unerfahrene Programmierer zu dem Schluss führen, dass auf diese Weise mehrere Dekorateure hintereinander aufgerufen werden können. Die Klammern werden benötigt, um alles ohne zusätzliche Einschränkungen oder komplexe Syntax zu verdeutlichen.
Ausgabe17005
Das neue Graphlib- Modul bietet Funktionen zum topologischen Sortieren eines Diagramms von Hash-Knoten.
Weitere Details finden Sie in der Dokumentation .
UPD :ifinik
>>> from graphlib import TopologicalSorter
>>> graph = {'E': {'C', 'F'}, 'D': {'B', 'C'}, 'B': {'A'}, 'A': {'F'}}
>>> ts = TopologicalSorter(graph)
>>> tuple(ts.static_order())
('C', 'F', 'E', 'A', 'B', 'D')
>>> tuple(ts.static_order())
('F', 'C', 'A', 'E', 'B', 'D')
Das Diagramm kann nicht sofort übertragen werden, sondern der TopologicalSorter mit der Methode add ausfüllen . Darüber hinaus ist die Klasse an paralleles Rechnen angepasst und kann beispielsweise zum Erstellen einer Aufgabenwarteschlange verwendet werden.
issue37630, issue40479
Aktualisieren der Hashlib-Bibliothek.
Hashlib kann jetzt SHA3- und SHAKE XOF-Hashes von OpenSSL verwenden.
Integrierte Hash-Module können jetzt deaktiviert oder selektiv aktiviert werden, um beispielsweise eine OpenSSL-basierte Implementierung zu erzwingen.
Optimierung
Eine Zusammenfassung der Leistungsverbesserungen von Python 3.4 auf Python 3.9:
Python version 3.4 3.5 3.6 3.7 3.8 3.9
-------------- --- --- --- --- --- ---
Variable and attribute read access:
read_local 7.1 7.1 5.4 5.1 3.9 4.0
read_nonlocal 7.1 8.1 5.8 5.4 4.4 4.8
read_global 15.5 19.0 14.3 13.6 7.6 7.7
read_builtin 21.1 21.6 18.5 19.0 7.5 7.7
read_classvar_from_class 25.6 26.5 20.7 19.5 18.4 18.6
read_classvar_from_instance 22.8 23.5 18.8 17.1 16.4 20.1
read_instancevar 32.4 33.1 28.0 26.3 25.4 27.7
read_instancevar_slots 27.8 31.3 20.8 20.8 20.2 24.5
read_namedtuple 73.8 57.5 45.0 46.8 18.4 23.2
read_boundmethod 37.6 37.9 29.6 26.9 27.7 45.9
Variable and attribute write access:
write_local 8.7 9.3 5.5 5.3 4.3 4.2
write_nonlocal 10.5 11.1 5.6 5.5 4.7 4.9
write_global 19.7 21.2 18.0 18.0 15.8 17.2
write_classvar 92.9 96.0 104.6 102.1 39.2 43.2
write_instancevar 44.6 45.8 40.0 38.9 35.5 40.7
write_instancevar_slots 35.6 36.1 27.3 26.6 25.7 27.7
Data structure read access:
read_list 24.2 24.5 20.8 20.8 19.0 21.1
read_deque 24.7 25.5 20.2 20.6 19.8 21.6
read_dict 24.3 25.7 22.3 23.0 21.0 22.5
read_strdict 22.6 24.3 19.5 21.2 18.9 21.6
Data structure write access:
write_list 27.1 28.5 22.5 21.6 20.0 21.6
write_deque 28.7 30.1 22.7 21.8 23.5 23.2
write_dict 31.4 33.3 29.3 29.2 24.7 27.8
write_strdict 28.4 29.9 27.5 25.2 23.1 29.8
Stack (or queue) operations:
list_append_pop 93.4 112.7 75.4 74.2 50.8 53.9
deque_append_pop 43.5 57.0 49.4 49.2 42.5 45.5
deque_append_popleft 43.7 57.3 49.7 49.7 42.8 45.5
Timing loop:
loop_overhead 0.5 0.6 0.4 0.3 0.3 0.3
Das Testskript zeigt die Zeit in Nanosekunden an. Die Tests wurden auf einem Intel Core i7-4960HQ-Prozessor durchgeführt . Der Testcode befindet sich im Repository unter " Tools / scripts / var_access_benchmark.py " .
Danke für die Aufmerksamkeit.
Link zum offiziellen Python 3.9- Handbuch .
Melden Sie sich in den Kommentaren ab, wenn Sie etwas verpasst haben.