Une des fonctionnalités qui me fait préférer Python à d'autre langage
est la possibilité d'utiliser des arguments nommés dans les fonctions
ou les méthodes.
Exemple en PHP
Je commence par écrire une fonction avec des paramètres optionnels :
<?php
function affiche_contact($nom, $prenom, $telephone1 = "", $telephone2 = "", $email = "")
{
print("Nom : $nom\n");
print("Prénom : $prenom\n");
print("Téléphone1 : $telephone1\n");
print("Téléphone2 : $telephone2\n");
print("Email : $email);
}
?>
J'affiche un contact sans spécifier aucun argument optionnel :
<?php
affiche_contact("Dupond", "Pierre");
?>
Jusque là tout va bien. A noter tout de même que sans lire l'entête de
la fonction, il n'est pas possible de savoir à quoi correspond chaque
argument. De plus il n'est pas possible d'envoyer en premier argument
le prénom puis le nom. L'entête de la fonction déclare que c'est
d'abord le nom, puis le prénom, il n'est pas possible de changer cet
ordre lors de l'appel de la fonction. Vous comprendrez ensuite
pourquoi j'ai donné cette précision.
J'affiche un contact mais cette fois je spécifie l'argument optionnel
$telephone1 :
<?php
affiche_contact("Dupond", "Pierre", "03 87 20 25 20");
?>
Toujours aucun problème, l'argument $telephone1 est le premier
argument optionnel.
Je souhaite maintenant afficher un contact avec un numéro de téléphone
et une adresse mail :
<?php
affiche_contact("Dupond", "Pierre", "03 87 20 25 20", "", "dupond.pierre@example.com");
?>
Comme vous pouvez le voir, si je souhaite passer le paramètre $email
je suis obligé d'envoyer l'argument $telephone2. Ceci n'est vraiment
pas pratique ni élégant. De plus, je dois avoir connaissance de la
valeur par défaut du paramètre que je ne souhaitais pas envoyer.
Ce cas de figure est une vrai limite au arguments optionnels des
fonctions du langage PHP. J'ai souvent été confronté à ce problème qui
est vraiment énervant lorsque l'on souhaite étendre les fonctionnalités
d'une fonction sans casser une API existante.
Exemple en Python
Je commence par écrire une fonction avec des paramètres optionnels :
def affiche_contact(nom, prenom, telephone1 = "", telephone2 = "", email = ""):
print ("""Nom : %s
Prénom : %s
Téléphone1 : %s
Téléphone2 : %s
Email : %s""" % (nom, prenom, telephone1, telephone2, email))
J'affiche un contact sans spécifier aucun arguement optionnel tout
comme avec la syntax PHP :
affiche_contact("Dupond", "Pierre")
Je peux aussi utiliser la syntaxe suivante :
affiche_contact(nom = "Dupond", prenom = "Pierre")
Cette syntaxe nous indique la correspondance de chaque champ envoyé.
Cela évite au lecteur de consulter l'entête de la fonction.
Je peux aussi envoyer les aguments dans un ordre quelconque :
affiche_contact(prenom = "Pierre", nom = "Dupond")
J'affiche un contact mais cette fois je spécifie l'arguement optionnel
telephone1 :
affiche_contact("Dupond", "Pierre", "03 87 20 25 20")
L'argument telephone1 est le premier arguement optionnel, il n'est
donc pas obligatoire de le nommer.
Je souhaite maintenant afficher un contact avec un numéro de téléphone
et une adresse mail :
affiche_contact("Dupond", "Pierre", "03 87 20 25 20", email = "dupond.pierre@example.com")
Comme vous pouvez le constater, j'ai envoyé uniquement les paramètres
optionnels que je souhaite transmettre, contrairement à PHP je n'ai
pas besoin de transmettre le paramètre telephone2.
Les arguments optionnels nommés sont vraiment une fonctionnalité
Python très pratique. Cela permet de vraiment choisir les paramètres
que l'on souhaite envoyer sans se soucier de l'ordre de ces derniers.
Les arguments nommés ont aussi l'avantage d'indiquer au lecteur le nom
de l'argument envoyé sans avoir à regarder l'entête de la fonction.
Solution de contournement en PHP
En PHP, il y a aussi une méthode pour produire plus ou moins le même
effet.
Exemple :
<?php
function affiche_contact($data)
{
if (!isset($data['telephone1'])) $data['telephone1'] = '';
if (!isset($data['telephone2'])) $data['telephone2'] = '';
if (!isset($data['email'])) $data['email'] = '';
print("Nom : " . $data['nom'] . "\n");
print("Prénom : " . $data['prenom'] . "\n");
print("Téléphone1 :" . $data['telephone1'] . "\n");
print("Téléphone2 :" . $data['telephone2'] . "\n");
print("Email :" . $data['email']);
}
?>
Puis lors de l'appel de la fonction :
<?php
affiche_contact(array("nom": "Dupond", "prenom": "Pierre"));
affiche_contact(array("nom": "Dupond", "prenom": "Pierre", "telephone1": "03 87 20 25 20"));
affiche_contact(array(
"nom" => "Dupond",
"prenom" => "Pierre",
"telephone1" => "03 87 20 25 20",
"email" => "dupond.pierre@example.com"
));
?>
Ceci est plus long (surtout dans le corps de la fonction) et moins
élégant qu'en Python où cette fonctionnalité est directement intégrée
au langage.
Conclusion
Je trouve que cette fonctionnalité du langage Python est très pratique
bien qu'elle ne soit pas une killer feature du langage.
Références
Pour finir, quelques références :