Stabile Version von Python 3.9.0

Die stabile Version von Python 3.9.0 wird voraussichtlich heute , am 05.10.2020, veröffentlicht. Die neue Version erhält ungefähr alle 2 Monate ungefähr 18 Monate lang gepatchte Updates. Einige Zeit nach der Veröffentlichung der endgültigen Version 3.10.0 wird das neunte und letzte Update mit Bugfixes 3.9 veröffentlicht.



„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



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,



  1. Der Parameter reuse_address asyncio.loop.create_datagram_endpoint () wird aufgrund erheblicher Sicherheitsprobleme nicht mehr unterstützt.
  2. 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

Bild



>>> 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.



All Articles