«Il s'agit de la première version de Python à utiliser par défaut le programme d'installation 64 bits sous Windows. Le programme d’installation interdit désormais activement l’installation sous Windows 7. »
«Il s'agit de la première version de Python à utiliser le programme d'installation 64 bits sur Windows par défaut. Le programme d'installation empêche désormais également l'installation sur Windows 7. "
J'ai lu les notes de publication de Python 3.9 et les discussions connexes. Sur la base des informations, j'ai voulu rédiger un guide complet afin que chacun puisse se faire une idée des fonctions ainsi que de leur travail détaillé.
UPD :
transition vers des cycles de publication annuels stables, voir PEP 602
alec_kalinin
«Chaque nouvelle version de Python sortira désormais en octobre. Python 3.10 sortira en octobre 2021, Python 3.11 en octobre 2022. Buckfix sortira tous les deux mois. C'est une excellente nouvelle pour moi, maintenant nous pouvons clairement planifier la mise à niveau de l'environnement python. "
PEP 584
Ce PEP suggère d'ajouter les opérateurs merge ( | ) et update ( | = ) à la classe dict intégrée.
Pour fusionner: |
>>> 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}
Pour mettre à jour: | =
>>> a | = b
>>> a
{'milk': 1, 'heese': 2, 'bread': 3}
La règle clé à retenir est qu'en cas de conflit de clé, la valeur la plus à droite sera conservée.
Bien sûr, de nombreux pythonistes auront une question, pourquoi est-ce nécessaire, s'il existe déjà une option familière à tout le monde
{**d1, **d2}
Cette question a été répondue dans le PEP lui-même:
Déballer des dictionnaires semble laid et n'est pas facile à détecter. Peu de gens pourront deviner ce que cela signifie lorsqu'ils le verront pour la première fois.
Comme l'a dit Guido :
Je m'excuse pour PEP 448 , mais même si vous connaissez ** d dans un contexte plus simple, si vous demandiez à un utilisateur Python typique comment combiner deux dict en un nouveau, je doute que beaucoup de gens pensent à {** d1, ** d2}. Je sais que je l'ai oublié moi-même quand ce fil a commencé!
De plus, {** d1, ** d2} ne fonctionne pas pour les sous-classes dict comme defaultdict
PEP 585
Conseils de type génériques dans les collections standard.
Le générique est un type paramétrable, une sorte de conteneur. Également appelé type paramétrique ou type générique.
Cette version inclut la prise en charge de la syntaxe universelle dans toutes les collections standard actuellement disponibles dans le module Typing. Nous pouvons utiliser des types list ou dict comme types génériques au lieu d'utiliser typing.List ou typing.Dict .
C'était:
from typing import List
a: List[str] = list()
def read_files(files: List[str]) -> None:
pass
Devenu:
a: list[str] = list()
def read_files(files: list[str]) -> None:
pass
Liste complète des types
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
Prise en charge de la base de données de fuseaux horaires IANA dans la bibliothèque standard.
Les fuseaux horaires de l'IANA sont souvent appelés tz ou informations de zone. Il existe un grand nombre de fuseaux horaires IANA avec différents chemins de recherche pour spécifier le fuseau horaire IANA pour un objet de date et d'heure. Par exemple, nous pouvons passer le nom du chemin de recherche Continent / City à un objet datetime pour définir son tzinfo.
dt: datetime = datetime(2000, 01, 25, 01, tzinfo=ZoneInfo("Europe/London"))
Si nous passons la mauvaise clé, une exception sera levée
zoneinfo.ZoneInfoNotFoundError
PEP 616
Nouvelles fonctions de chaîne pour supprimer le préfixe et le suffixe. Deux nouvelles fonctions ont été ajoutées
à l' objet str .
- La première fonction supprime le préfixe.
str.removeprefix(prefix)
- La deuxième fonction supprime le suffixe.
str.removesuffix(suffix)
>>> 'hello_world'.removeprefix ('hello_')
world
>>> 'hello_world'.removesuffix ('_world')
hello
PEP 617
Python 3.9 propose de remplacer l'analyseur Python actuel basé sur LL (1) par un nouvel analyseur basé sur PEG qui est haute performance et stable.
L'analyseur CPython actuel est basé sur LL (1). Par la suite, la grammaire est basée sur LL (1), ce qui lui permet d'être analysée avec un analyseur LL (1). L'analyseur LL (1) fonctionne de haut en bas. De plus, il analyse les données d'entrée de gauche à droite. La grammaire actuelle est une grammaire sans contexte, donc le contexte des jetons n'est pas pris en compte.
Python 3.9 propose de le remplacer par un nouvel analyseur basé sur PEG, ce qui signifie qu'il supprimera les limitations actuelles de la grammaire LL de Python (1). De plus, des correctifs ont été apportés à l'analyseur actuel, ajoutant un certain nombre de hacks qui seront supprimés. En conséquence, cela réduira le coût de la maintenance à long terme.
Par exemple, alors que les analyseurs et les grammaires LL (1) sont faciles à implémenter, les contraintes les empêchent d'exprimer des constructions communes de manière naturelle pour le concepteur du langage et le lecteur. L'analyseur ne regarde qu'un seul jeton vers l'avant pour distinguer les possibilités.
issue30966
Possibilité d'annuler des contrats à terme simultanés .
Un nouveau paramètre cancel_futures a été ajouté à concurrent.futures.Executor.shutdown () .
Ce paramètre contient tous les futurs en attente qui n'ont pas encore démarré. Avant la version 3.9, le processus attendait leur fin avant de quitter l'exécuteur.
Un nouveau paramètre cancel_futures a été ajouté à ThreadPoolExecutor et ProcessPoolExecutor . Cela fonctionne lorsque la valeur du paramètre est True, alors tous les contrats à terme en attente seront annulés lorsque la fonction shutdown () est appelée .
Lors de l' arrêt ()est exécuté, l'interpréteur vérifie si l'exécuteur est ramassé. S'il est toujours en mémoire, il récupère tous les éléments en attente, puis annule les contrats à terme.
issue30966
Un certain nombre d'améliorations ont été apportées à la bibliothèque asyncio et multitraitement dans cette version.
Par exemple,
- Le paramètre reuse_address asyncio.loop.create_datagram_endpoint () n'est plus pris en charge en raison de problèmes de sécurité importants.
- Ajout de nouvelles coroutines, shutdown_default_executor () et asyncio.to_thread () . Un nouvel appel à asyncio.to_thread () est utilisé pour exécuter des fonctions liées aux E / S sur un thread séparé pour éviter de bloquer la boucle d'événements.
En ce qui concerne les améliorations apportées à la bibliothèque multitraitement, une nouvelle méthode close () a été ajoutée à la classe multiprocessing.SimpleQueue . Cette méthode ferme explicitement la file d'attente. Cela garantit que la file d'attente est fermée et ne reste pas plus longtemps que prévu. Il est important de se rappeler que les méthodes get (), put (), empty () ne peuvent pas être appelées après la fermeture de la file d'attente.
issue37444
Correction d'un bug avec l'importation de packages.
Le principal problème avec l'importation de bibliothèques Python avant la version 3.9 était le comportement d'importation incohérent dans Python lorsque les importations relatives passaient par son package de niveau supérieur.
builtins .__ import __ () a déclenché une ValueError tandis que importlib .__ import __ () a déclenché une ImportError.
Maintenant c'est corrigé . __Import __ () lève désormais ImportError au lieu de ValueError.
issue40286
Génération d'octets aléatoires.
Une autre fonctionnalité qui a été ajoutée dans la version 3.9 est random.Random.randbytes () . Il peut être utilisé pour générer des octets aléatoires.
Nous pouvons générer des nombres aléatoires, mais que faire si nous devions générer des octets aléatoires? Avant la version 3.9, les développeurs devaient être créatifs pour générer des octets aléatoires. Bien que nous puissions utiliser os.getrandom () , os.urandom () ou secrets.token_bytes (), nous ne pouvons pas générer de modèles pseudo-aléatoires.
Par exemple, pour garantir que les nombres aléatoires sont générés avec le comportement attendu et que le processus se reproduit, nous utilisons généralement des valeurs de départ avec le module random.Random.
En conséquence, la méthode random.Random.randbytes () a été introduite . Il génère des octets aléatoires.
issue28029
Correction de la fonction de remplacement de chaîne.
Le principe de la fonction replace est que pour un argument maximum donné pour remplacer une occurrence, elle remplace le jeu de caractères de la chaîne par le nouveau jeu de caractères.
Pour expliquer davantage le problème, avant la version 3.9, la fonction de remplacement avait un comportement incohérent:
on s'attendrait à voir le blog
"" .replace ("", "blog", 1)
>>> ''
On s'attendrait à voir |
"" .replace ("", "|", 1)
>>> ''
"" .replace ("", "prefix")
>>> 'prefix'
issue39648, issue39479, issue39288, issue39310
Modifications dans le module "maths".
Renvoie le plus petit multiple commun d'arguments entiers:
>>> import math
>>> math.lcm(48,72,108)
432
Renvoie le plus grand diviseur commun d'arguments entiers. La version antérieure ne prenait en charge que deux arguments. Ajout de la prise en charge d'un nombre arbitraire d'arguments:
>>> import math
>>> math.gcd(9,12,21)
3
Calcule le nombre à virgule flottante le plus proche de " x " dans la direction de " y ".
>>> math.nextafter(2, -1)
1.9999999999999998
Cette méthode renvoie la valeur du bit le moins significatif du nombre à virgule flottante x.
>>> 1 - math.ulp(1)
0.9999999999999998
>>> math.nextafter(1, -1) + math.ulp(1)
1.0
problème38870
La méthode unparse a été ajoutée au module ast.
La nouvelle méthode peut être utilisée pour créer une ligne de code puis l'exécuter.
>>> 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
issue39507, issue39509
Ajout de nouveaux codes à http.HTTPStatus.
" Économisez 418! "
418 IM_A_TEAPOT
103 EARLY_HINTS
425 TOO_EARLY
UPD :
PEP 614
Assouplissement des restrictions grammaticales pour les décorateurs.
C'était:
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():
...
Vous pouvez désormais supprimer les affectations inutiles et appeler directement:
buttons = [QPushButton(f'Button {i}') for i in range(10)]
@buttons[0].clicked.connect
def spam():
...
@buttons[1].clicked.connect
def eggs():
...
«Le tuple doit être placé entre parenthèses.»
Ceci est basé sur la vision de Guido dans la même lettre. Citation:
Mais je n'autoriserai pas les virgules. Je ne peux pas être d'accord avec ça
@f, g def pooh(): ...
Cela peut conduire les programmeurs inexpérimentés à la conclusion que plusieurs décorateurs peuvent être appelés de cette manière. Les parenthèses sont nécessaires pour tout clarifier sans restrictions supplémentaires ni syntaxe complexe.
issue17005
Le nouveau module graphlib fournit des fonctionnalités pour le tri topologique d'un graphe de nœuds hachés.
Plus de détails peuvent être trouvés dans la documentation .
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')
Le graphe peut être transféré non immédiatement, mais remplissez le TopologicalSorter en utilisant la méthode add . De plus, la classe est adaptée au calcul parallèle et peut être utilisée, par exemple, pour créer une file d'attente de tâches.
issue37630, issue40479
Mise à jour de la bibliothèque hashlib.
Hashlib peut désormais utiliser les hachages SHA3 et SHAKE XOF d'OpenSSL.
Les modules de hachage intégrés peuvent désormais être désactivés ou activés de manière sélective, par exemple pour appliquer une implémentation basée sur OpenSSL.
Optimisation
Un résumé des améliorations de performances de Python 3.4 à 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
Le script de test affiche l'heure en nanosecondes. Les tests ont été réalisés sur un processeur Intel Core i7-4960HQ . Le code de test se trouve dans le référentiel sous " Tools / scripts / var_access_benchmark.py " .
Merci de votre attention.
Lien vers le manuel officiel de Python 3.9.
Désabonnez-vous dans les commentaires si vous avez manqué quelque chose.