Chaînes F ou comment rendre le code un peu plus rapide et plus lisible



Python a 3 façons de formater les chaînes, et l'une d'entre elles est meilleure que les autres. Mais n'allons pas de l'avant - de quel type de formatage parlons-nous? Chaque fois que nous voulons saluer un utilisateur par son nom, nous devons insérer une chaîne avec un nom dans la chaîne de modèle. Les entrées de journal les plus utiles contiennent également des valeurs variables. Et voici un exemple:

integer = 42 string = 'FORTY_TWO' print('string number %s, or simply %d' % (string, integer)) print('string number {}, or simply {}'.format(string, integer)) print(f'string number {string}, or simply {integer}') 

La première méthode, formatée avec l'opérateur%, est venue en Python de C - elle imite la fonction printf. Cette méthode était la première en python et reste la seule (discutée dans l'article) en Python version 2.5 et inférieure.

La deuxième façon est la méthode str.format, qui appartient à la classe de chaîne intégrée. Il est venu avec Python 3.0 et a été porté à la version 2.6. Cette méthode a été recommandée comme ayant une syntaxe plus riche.

La troisième méthode, f-string, est apparue dans Python version 3.6. Comme expliqué dans PEP-0498 , la création d'une nouvelle façon de formater les chaînes a été motivée par les lacunes des méthodes existantes, que les auteurs caractérisent comme sujettes aux erreurs, pas assez flexibles et pas élégantes:
Ce PEP est motivé par le désir d'avoir un moyen plus simple de formater les chaînes en Python. Les méthodes de formatage existantes sont sujettes aux erreurs, inflexibles ou encombrantes.
Nous avons donc trois façons de résoudre un problème. Mais c'est peut-être une question de goût et de préférence personnels? Peut-être, mais le style de votre code (en particulier le code d'un projet avec un grand nombre de participants) bénéficiera certainement de l'uniformité. Dans le meilleur des cas, vous devez utiliser une méthode de formatage des chaînes, il deviendra alors plus facile de lire le code. Mais quelle méthode choisir? Et y a-t-il une différence dans les performances du code?

Essayons de répondre expérimentalement à la question sur les performances:

 import timeit setup = """ integer = 42 string = 'FORTY_TWO' """.strip() percent_stmt ="'Number %s or simply %d' % (string, integer)" call_stmt = "'Number {} or simply {}'.format(string, integer)" fstr_stmt = """f'Number {string} or simply {integer}'""" def time(stmt): return f"{timeit.timeit(stmt, setup, number=int(1e7)):.3f}" print(f"Timing percent formating: | {time(percent_stmt)}") print(f"Timing call formating: | {time(call_stmt)}") print(f"Timing f-string formating: | {time(fstr_stmt)}") 

Résultats sur MacBook avec Python 3.7:

 Timing percent formating: | 2.025 Timing call formating: | 2.943 Timing f-string formating: | 1.348 

La différence est significative. Alors maintenant, lancez la recherche d'expression régulière sur ".format" et réécrivez des centaines d'expressions? En principe, la tâche est simple mais prend du temps. Plus la chance de faire une erreur et de mettre un bug dans le code qui fonctionnait auparavant! Il semble qu'il y ait de la place pour l'automatisation. En effet, il existe des bibliothèques qui peuvent convertir la plupart des expressions en chaînes f: flynt , pyupgrade .

Flynt est facile à utiliser. Par exemple, exécutez la conversion sur le code source du flacon:

 38f9d3a65222:~ ikkamens$ git clone https://github.com/pallets/flask.git Cloning into 'flask'... ... Resolving deltas: 100% (12203/12203), done. 38f9d3a65222:~ ikkamens$ flynt flask Flynt run has finished. Stats: Execution time: 0.623s Files modified: 18 Expressions transformed: 43 Character count reduction: 241 (0.04%) _-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_. Please run your tests before commiting. Report bugs as github issues at: https://github.com/ikamensh/flynt Thank you for using flynt! Fstringify more projects and recommend it to your colleagues! _-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_. 38f9d3a65222:~ ikkamens$ 

Il convient également de noter la possibilité de convertir des expressions qui occupent plusieurs lignes et de collecter des statistiques sur les modifications apportées. L'indicateur --line_length XX définit la limite de longueur de ligne après la conversion. Flynt vous permet d'appeler pyupgrade avec le drapeau --upgrade.

Pyupgrade inclut plus de fonctionnalités et peut nettoyer votre code de nombreux artefacts Python 2 - tels que l'héritage d'un objet, la spécification de noms de classe en super, et bien plus encore . Pyupgrade est conçu pour être utilisé avec pre-commit , un utilitaire pour modifier automatiquement le code avant les validations .

Il est préférable de convertir la source dans une gita ou un autre contrôle de version. Cela vaut la peine d'exécuter des tests et d'examiner les modifications vous-même (en utilisant les environnements git diff ou PyCharm). Tant que nous vivons parmi ceux qui s'en soucient, que le code est devenu plus court de quelques caractères, une conversion proactive leur fera également gagner du temps. Après tout, tôt ou tard, quelqu'un commencera à faire de ses mains ce qui peut devenir un utilitaire. Les chaînes F ne fonctionnent que sur Python 3.6+, mais bientôt ce ne sera pas un problème car les autres versions deviendront obsolètes .

Il convient de noter que la méthode .format classique ne fonctionnera pas complètement. Dans le cas où vous utilisez le même modèle pour créer des messages avec différentes variables à différents endroits du code, vous devez enregistrer ce modèle dans une variable et l'utiliser - le principe «Ne vous répétez pas» est beaucoup plus important que les nanosecondes gagnées en formatant une chaîne.

Conclusions:

Nous avons examiné les trois méthodes de formatage de chaînes disponibles dans Python 3.6+, leur bref historique et comparé leurs performances. Nous avons également examiné les outils open-source pour convertir automatiquement le code en une nouvelle méthode de formatage des chaînes et leurs fonctions supplémentaires. N'oubliez pas les choses simples de votre code et bonne chance!

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


All Articles