Certaines bibliothèques Python, comme pandas, NumPy et Pillow (PIL), sont conçues pour permettre le chaînage de méthodes, où les méthodes peuvent être liées de manière séquentielle.
Bien que le chaînage de méthodes ait tendance à augmenter la longueur d’une ligne de code, l’utilisation de parenthèses permet des sauts de ligne appropriés.
Cet article explique d’abord comment écrire un chaînage de méthodes avec des sauts de ligne en utilisant pandas comme exemple, puis présente des exemples utilisant NumPy et Pillow (PIL).
- Enchaînement de méthodes dans pandas
- Rupture de lignes entre parenthèses
- Utiliser des barres obliques inverses
- Entourez la chaîne de méthodes entre parenthèses ()
- Le formateur de code Black recommande d’utiliser des parenthèses
- Enchaînement de méthodes dans NumPy
- Chaînage de méthodes dans Pillow (PIL)
Notez que le guide de style Python, PEP8, inclut des sections sur l’indentation mais ne spécifie pas de directives pour le chaînage des méthodes.
Le formateur de code plus strict Black recommande d’utiliser des parenthèses pour le chaînage de méthodes multilignes, comme mentionné plus tard.
Enchaînement de méthodes dans pandas
Dans pandas, de nombreuses méthodes de D𝐚𝐭𝐚F𝐫𝐚𝐦𝐞 ou S𝐞𝐫𝐢𝐞𝐬 retournent un D𝐚𝐭𝐚F𝐫𝐚𝐦𝐞 ou S𝐞𝐫𝐢𝐞𝐬 , permettant le chaînage de méthodes.
Tout d’abord, considérons l’exemple suivant sans chaînage de méthodes.
Lisez un fichier CSV avec 𝐩𝐝.𝐫𝐞𝐚𝐝_𝐜𝐬𝐯() .
import pandas as pd df = pd.read_csv('data/src/sample_pandas_normal.csv', index_col=0) print(df) # age state point # name # Alice 24 NY 64 # Bob 42 CA 92 # Charlie 18 CA 70 # Dave 68 TX 70 # Ellen 24 CA 88 # Frank 30 NY 57
À ce D𝐚𝐭𝐚F𝐫𝐚𝐦𝐞 , ajoutez une nouvelle colonne, supprimez les colonnes inutiles, triez les données et extrayez uniquement les trois premières lignes.
- pandas : ajouter des lignes/colonnes au DataFrame avec assign(), insert()
- pandas : supprime les lignes/colonnes du DataFrame avec drop()
- pandas : trier les DataFrame/Series avec sort_values(), sort_index()
- pandas : obtenir les n premières/dernières lignes du DataFrame avec head() et tail()
df = df.assign(point_ratio=df['point'] / 100) df = df.drop(columns='state') df = df.sort_values('age') df = df.head(3) print(df) # age point point_ratio # name # Charlie 18 70 0.70 # Alice 24 64 0.64 # Ellen 24 88 0.88
Le même processus peut être écrit avec un chaînage de méthodes comme suit. Il est intentionnellement écrit sur une seule ligne.
df_mc = pd.read_csv('data/src/sample_pandas_normal.csv', index_col=0).assign(point_ratio=df['point'] / 100).drop(columns='state').sort_values('age').head(3) print(df_mc) # age point point_ratio # name # Charlie 18 70 0.70 # Alice 24 64 0.64 # Ellen 24 88 0.88
Bien que l’enchaînement de méthodes soit pratique et simple, enchaîner de nombreuses méthodes sans bien les comprendre peut conduire à des résultats inattendus. Si vous n’êtes pas familier avec les méthodes, il peut être plus de les appliquer une par une sûre et de vérifier les résultats.
De plus, selon l’éditeur, il peut y avoir des inconvénients comme la saisie semi-automatique qui ne fonctionne pas pour la deuxième méthode et les suivantes.
Rupture de lignes entre parenthèses
Python autorise les sauts de ligne à l’intérieur des parenthèses, comme indiqué ci-dessous. Les résultats sont les mêmes dans tous les cas, ils sont donc omis.
df_mc_break = pd.read_csv( 'data/src/sample_pandas_normal.csv', index_col=0 ).assign( point_ratio=df['point'] / 100 ).drop( columns='state' ).sort_values( 'age' ).head( 3 )
Cependant, il est important de noter que la rupture des lignes à l’intérieur des littéraux de chaîne peut provoquer des erreurs.
# df_mc_break = pd.read_csv( # 'data/src/sample_ # pandas_normal.csv', # index_col=0 # ).assign( # point_ratio=df['point'] / 100 # ).drop( # columns='state' # ).sort_values( # 'age' # ).head( # 3 # ) # SyntaxError: unterminated string literal (detected at line 2)
Bien sûr, il n’est pas nécessaire de couper les lignes partout ; vous pouvez choisir de le faire uniquement dans des segments plus longs si vous le préférez.
df_mc_break = pd.read_csv( 'data/src/sample_pandas_normal.csv', index_col=0 ).assign( point_ratio=df['point'] / 100 ).drop(columns='state').sort_values('age').head(3)
Utiliser des barres obliques inverses
En Python, une barre oblique inverse ( \ ) agit comme un caractère de continuation, permettant à une ligne de continuer au-delà d’un saut de ligne.
df_mc_backslash = pd.read_csv('data/src/sample_pandas_normal.csv', index_col=0) \ .assign(point_ratio=df['point'] / 100) \ .drop(columns='state') \ .sort_values('age') \ .head(3)
Entourez la chaîne de méthodes entre parenthèses ()
En exploitant la règle de Python qui autorise les sauts de ligne libres entre parenthèses, l’inclusion de toute la chaîne de méthodes entre () permet une rupture flexible.
df_mc_parens = ( pd.read_csv('data/src/sample_pandas_normal.csv', index_col=0) .assign(point_ratio=df['point'] / 100) .drop(columns='state') .sort_values('age') .head(3) )
Dans ce cas, vous êtes également libre d’utiliser ou non des sauts de ligne, vous pouvez donc écrire comme suit.
df_mc_parens = (pd.read_csv('data/src/sample_pandas_normal.csv', index_col=0) .assign(point_ratio=df['point'] / 100) .drop(columns='state') .sort_values('age') .head(3))
Placer un point ( . ) à la fin d’une ligne n’est pas une erreur mais peut masquer la présence d’un chaînage de méthodes. Il est préférable d’éviter cette pratique.
df_mc_parens = ( pd.read_csv('data/src/sample_pandas_normal.csv', index_col=0). assign(point_ratio=df['point'] / 100). drop(columns='state'). sort_values('age'). head(3) )
De la même manière, vous pouvez écrire une longue chaîne en utilisant des parenthèses pour séparer les lignes du code. Voir l’article suivant.
Le formateur de code Black recommande d’utiliser des parenthèses
Bien que le guide de style Python, PEP8, ne recommande pas de directives spécifiques pour le chaînage des méthodes, le formateur de code plus strict Black recommande d’utiliser des parenthèses et de rompre les lignes avant les points.
- psf/black : le formateur de code Python sans compromis
- Le style Black code – Chaînes d’appel – Documentation Black 23.9.1
df_mc_parens = ( pd.read_csv('data/src/sample_pandas_normal.csv', index_col=0) .assign(point_ratio=df['point'] / 100) .drop(columns='state') .sort_values('age') .head(3) )
Enchaînement de méthodes dans NumPy
Dans NumPy, plusieurs méthodes de 𝐧𝐝𝐚𝐫𝐫𝐚𝐲 renvoient 𝐧𝐝𝐚𝐫𝐫𝐚𝐲 .
Exemple sans chaînage de méthodes :
- NumPy : arange() et linspace() pour générer des valeurs espacées
- NumPy : reshape() pour changer la forme d’un tableau
- NumPy : clip() pour limiter les valeurs du tableau à min et max
import numpy as np a = np.arange(12) a = a.reshape(3, 4) a = a.clip(2, 9) print(a) # [[2 2 2 3] # [4 5 6 7] # [8 9 9 9]]
Exemple avec chaînage de méthodes :
a_mc = np.arange(12).reshape(3, 4).clip(2, 9) print(a_mc) # [[2 2 2 3] # [4 5 6 7] # [8 9 9 9]]
Mettre entre parenthèses et couper les lignes :
a_mc_parens = ( np.arange(12) .reshape(3, 4) .clip(2, 9) ) print(a_mc_parens) # [[2 2 2 3] # [4 5 6 7] # [8 9 9 9]]
Notez que dans NumPy, de nombreuses opérations sont définies comme des fonctions qui prennent un 𝐧𝐝𝐚𝐫𝐫𝐚𝐲 comme argument, plutôt que des méthodes de 𝐧𝐝𝐚𝐫𝐫𝐚𝐲 lui-même. Ainsi, tout ne peut pas être réalisé via le chaînage de méthodes comme dans pandas.
Chaînage de méthodes dans Pillow (PIL)
La bibliothèque de traitement d’images Pillow (PIL) représente les images de type I𝐦𝐚𝐠𝐞 . Certaines méthodes de I𝐦𝐚𝐠𝐞 renvoient un I𝐦𝐚𝐠𝐞 , ce qui permet le chaînage des méthodes.
Exemple sans chaînage de méthodes :
from PIL import Image, ImageFilter im = Image.open('data/src/lena_square.png') im = im.convert('L') im = im.rotate(90) im = im.filter(ImageFilter.GaussianBlur()) im.save('data/temp/lena_square_pillow.jpg', quality=95)
Exemple avec chaînage de méthodes :
Image.open('data/src/lena_square.png').convert('L').rotate(90).filter(ImageFilter.GaussianBlur()).save('data/temp/lena_square_pillow.jpg', quality=95)
Mettre entre parenthèses et couper les lignes :
( Image.open('data/src/lena_square.png') .convert('L') .rotate(90) .filter(ImageFilter.GaussianBlur()) .save('data/temp/lena_square_pillow.jpg', quality=95) )
Comme le montre cet exemple, effectuer des opérations allant de la lecture à l’enregistrement dans une seule chaîne sans affecter de valeurs de retour aux variables peut sembler un peu étrange lorsque le tout est entouré de parenthèses.
Par exemple, le formateur de code Black suggère de ne pas utiliser de parenthèses dans de tels cas, proposant à la place le style suivant.
Image.open('data/src/lena_square.png').convert('L').rotate(90).filter( ImageFilter.GaussianBlur() ).save('data/temp/lena_square_pillow.jpg', quality=95)