Les fonctionnalités de Python 3 méritent d'être utilisées

De nombreux programmeurs ont commencé à passer de la deuxième version de Python à la troisième en raison du fait que la prise en charge de Python 2 sera bientôt abandonnée . L'auteur de l'article, dont nous publions la traduction, note que la majeure partie du code Python 3 qu'il a vu, ressemble à un code entre crochets, écrit en Python 2. Selon lui, il pèche lui-même quelque chose comme ça . Ici, il donne des exemples de certaines des grandes fonctionnalités disponibles uniquement pour ceux qui utilisent Python 3. Il espère que ces fonctionnalités rendront la vie plus facile pour ceux qui en apprennent plus.



Tous les exemples de cet article sont écrits à l'aide de Python 3.7. La description de chaque fonctionnalité contient des informations sur la version minimale de Python nécessaire à son utilisation.

Format des chaînes (3.6+)


Sans chaînes, il est difficile d'écrire quelque chose d'utile dans n'importe quel langage de programmation. Mais pour un travail efficace avec des chaînes, un développeur a besoin d'outils pratiques. De tels outils qui vous permettent de travailler avec des structures complexes sans perdre votre tranquillité d'esprit. La plupart des développeurs Python utilisent la méthode de format :

 user = "Jane Doe" action = "buy" log_message = 'User {} has logged in and did an action {}.'.format( user, action ) print(log_message) # User Jane Doe has logged in and did an action buy. 

Python 3, avec la méthode de format , prend en charge les chaînes de formatage ( chaînes f, chaînes f). Ils sont un outil flexible pour effectuer diverses manipulations de cordes. Voici à quoi ressemble l'exemple précédent, réécrit à l'aide de chaînes de format:

 user = "Jane Doe" action = "buy" log_message = f'User {user} has logged in and did an action {action}.' print(log_message) # User Jane Doe has logged in and did an action buy. 

Module Pathlib (3.4+)


Les chaînes de format sont une excellente technologie, mais des outils spéciaux ont été créés pour fonctionner avec certaines lignes, comme les chemins de fichiers, ce qui simplifie considérablement leur manipulation. Python 3 possède un module pathlib , qui est une abstraction pratique pour travailler avec des chemins de fichiers. Si vous n'êtes pas encore sûr de l'utilité de ce module pour résoudre vos problèmes, jetez un œil à ce matériel.

 from pathlib import Path root = Path('post_sub_folder') print(root) # post_sub_folder path = root / 'happy_user' #    print(path.resolve()) # /home/weenkus/Workspace/Projects/DataWhatNow-Codes/how_your_python3_should_look_like/post_sub_folder/happy_user 

Annotations de type (3.5+)


Quel est le meilleur - typage statique ou dynamique? Peut-être que presque tous les programmeurs ont leur propre réponse à cette question difficile. Je laisse au lecteur la façon dont ils décrivent exactement leurs programmes. Mais je pense qu'il est bon pour tout le monde de savoir au moins que Python 3 prend en charge les annotations de type .

 def sentence_has_animal(sentence: str) -> bool: return "animal" in sentence sentence_has_animal("Donald had a farm without animals") # True 

Transferts (3.4+)


Python 3 prend en charge, grâce à la classe Enum , un mécanisme simple pour travailler avec des énumérations . Les énumérations sont pratiques pour stocker des listes de constantes. Sinon, les constantes sont dispersées de façon aléatoire dans le code.

 from enum import Enum, auto class Monster(Enum):   ZOMBIE = auto()   WARRIOR = auto()   BEAR = auto()  print(Monster.ZOMBIE) # Monster.ZOMBIE 

À partir de la documentation Python 3, vous pouvez découvrir qu'une énumération est une collection de noms symboliques (membres) liés à des valeurs uniques et immuables. Les membres d'une seule liste peuvent être comparés pour leur identité. Les énumérations peuvent être contournées.

 for monster in Monster:   print(monster) # Monster.ZOMBIE # Monster.WARRIOR # Monster.BEAR 

Cache LRU intégré (3.2+)


De nos jours, les mécanismes de mise en cache sont utilisés dans presque tous les systèmes logiciels et matériels. Python 3 simplifie considérablement la mise en cache avec le décorateur lru_cache , qui implémente l'algorithme de mise en cache LRU (le moins récemment utilisé ).

Voici une fonction qui calcule les nombres de Fibonacci. Cette fonction est forcée plusieurs fois d'effectuer les mêmes opérations lors d'appels récursifs. En conséquence, il s'avère que ses performances peuvent être améliorées grâce à la mise en cache.

 import time def fib(number: int) -> int:   if number == 0: return 0   if number == 1: return 1     return fib(number-1) + fib(number-2) start = time.time() fib(40) print(f'Duration: {time.time() - start}s') # Duration: 30.684099674224854s 

Nous utilisons maintenant lru_cache pour optimiser cette fonction (cette technique d'optimisation est appelée mémorisation ). Par conséquent, le temps d'exécution d'une fonction qui était auparavant mesuré en secondes est désormais mesuré en nanosecondes.

 from functools import lru_cache @lru_cache(maxsize=512) def fib_memoization(number: int) -> int:   if number == 0: return 0   if number == 1: return 1     return fib_memoization(number-1) + fib_memoization(number-2) start = time.time() fib_memoization(40) print(f'Duration: {time.time() - start}s') # Duration: 6.866455078125e-05s 

Déballage des objets itérables (3.0+)


Lorsque vous décompressez des objets itérables, vous pouvez utiliser des variables dont les noms sont précédés d'un astérisque. Tout ce qui ne rentre pas dans d'autres variables entre dans de telles variables. Ainsi, dans l'exemple suivant, les première et dernière valeurs de la liste formée par la commande range(5) tombent dans les variables head et tail . Tout ce qui se trouve entre la première et la dernière valeur entre dans la variable body .

 head, *body, tail = range(5) print(head, body, tail) # 0 [1, 2, 3] 4 py, filename, *cmds = "python3.7 script.py -n 5 -l 15".split() print(py) print(filename) print(cmds) # python3.7 # script.py # ['-n', '5', '-l', '15'] first, _, third, *_ = range(10) print(first, third) # 0 2 

Classes de données (3.7+)


Python 3 a introduit les classes de données . Ils donnent au programmeur une grande liberté d'action. Ils peuvent être utilisés pour réduire la quantité de code passe-partout. Le fait est que le décorateur de dataclass de données génère automatiquement des méthodes spéciales, telles que __init__() et __repr__() . Dans le texte officiel de la proposition correspondante , ils sont décrits comme des "tuples nommés mutables avec des valeurs par défaut". Voici un exemple de création d'une classe sans utiliser le décorateur de classe de dataclass :

 class Armor:     def __init__(self, armor: float, description: str, level: int = 1):       self.armor = armor       self.level = level       self.description = description                  def power(self) -> float:       return self.armor * self.level  armor = Armor(5.2, "Common armor.", 2) armor.power() # 10.4 print(armor) # <__main__.Armor object at 0x7fc4800e2cf8> 

Voici la même chose, mais déjà écrite à l'aide de la dataclass :

 from dataclasses import dataclass @dataclass class Armor:   armor: float   description: str   level: int = 1     def power(self) -> float:       return self.armor * self.level  armor = Armor(5.2, "Common armor.", 2) armor.power() # 10.4 print(armor) # Armor(armor=5.2, description='Common armor.', level=2) 

Prise en charge des dossiers de packages sans le fichier __init__.py (3.3+)


Une façon de structurer le code Python consiste à utiliser des packages (les packages sont placés dans des dossiers contenant le fichier __init__.py ). Voici un exemple tiré de la documentation officielle:

 sound/                                 __init__.py                 sound     formats/                                   __init__.py             wavread.py             wavwrite.py             aiffread.py             aiffwrite.py             auread.py             auwrite.py             ...     effects/                                  __init__.py             echo.py             surround.py             reverse.py             ...     filters/                                 __init__.py             equalizer.py             vocoder.py             karaoke.py             ... 

Lorsque vous utilisez Python 2, chacun des dossiers mentionnés dans l'exemple doit avoir un fichier __init__.py . Grâce à ce fichier, le dossier est perçu comme un package Python. Dans Python 3, avec l'avènement de la fonctionnalité Implicit Namespace Packages , des dossiers comme ceux-ci ne sont plus nécessaires.

 sound/                                 __init__.py                 sound     formats/                                   wavread.py             wavwrite.py             aiffread.py             aiffwrite.py             auread.py             auwrite.py             ...     effects/                                  echo.py             surround.py             reverse.py             ...     filters/                                 equalizer.py             vocoder.py             karaoke.py             ... 

Il convient de noter qu'en fait, tout n'est pas si simple. À savoir, selon cette spécification officielle, le fichier __init__.py est toujours nécessaire pour les packages réguliers. Si vous le supprimez du dossier, le package se transforme en un soi-disant package d'espace de noms , auquel des restrictions supplémentaires s'appliquent.

Résumé


Toutes les fonctionnalités intéressantes de Python 3 ne sont pas couvertes dans cet article, mais nous espérons que vous trouverez quelque chose d'utile ici. Un exemple de code se trouve dans ce référentiel.

Chers lecteurs! Quelles fonctionnalités de Python 3 ajouteriez-vous à la liste ici?

Source: https://habr.com/ru/post/fr452564/


All Articles