web-dev-qa-db-fra.com

Quel style utiliser pour les paramètres de retour inutilisés dans un appel de fonction Python

Existe-t-il un style de codage recommandé/généralement accepté pour gérer les situations dans lesquelles une fonction renvoie un tuple de valeurs, mais une seule de ces valeurs est utilisée par la suite (notez que cela est principalement destiné aux fonctions de bibliothèque que je ne peux pas modifier - écrire un wrapper autour l'appel est probablement un peu exagéré…)? Au lieu de faire

a, b, c = foo()

et puis simplement ne pas utiliser b et c, laquelle des variantes suivantes devrait être préférée (ou y en a-t-il une autre?):

Variante 1 (soulignement)

a, _, _ = foo()

(ce qui est très clair et simple mais pourrait entrer en conflit avec _ = gettext.gettext utilisé dans de nombreuses applications qui utilisent la traduction)

Variante 2 (nom fictif)

a, unused, unused = foo()

(pas très attrayant, je pense, il en va de même pour d'autres noms comme dummy)

Variante 3 (index)

a = foo()[0]

(pour moi le ()[0] semble non-pythonique…)

31
user49643

L'utilisation du trait de soulignement pour les variables inutilisées est certainement acceptable. Soyez averti cependant, dans certaines bases de code, ce n'est pas une option car cet identifiant est réservé en raccourci pour gettext. C'est l'objection la plus fréquente à ce style (bien que ce ne soit pas un problème pour la majorité pour autant que je puisse en juger). Je le recommanderais toujours et je l'utiliserais toujours moi-même.

Des noms comme dummy ou unused ont tendance à m'énerver personnellement, et je ne les vois pas très souvent (en Python, c'est-à-dire que je connais une base de code Delphi qui utilise dummy libéralement, et il s'est également infiltré dans des scripts associés au programme en question). Je vous déconseille.

Il suffit également d'extraire un élément du tuple retourné. Cela évite également quelques tracas pour obtenir le bon nombre de valeurs inutilisées. Notez cependant qu'il a deux inconvénients potentiels:

  • Il ne souffle pas si le nombre de valeurs est différent de ce que vous attendez. Cela peut être utile pour détecter les mélanges et les fautes de frappe.
  • Cela ne fonctionne que lorsque la valeur de retour est une séquence (c'est principalement des tuples et des listes, mais restons généraux). Offhand, je connais une classe dans mon code (un vecteur 2D) qui est itérable et donne un nombre constant de valeurs (et peut donc être utilisé dans le déballage des affectations), mais n'est pas indexable.
17
user7043

Pylint m'a donné l'habitude de le faire de cette façon:

widget, _parent, _children = f()

Autrement dit, les résultats inutilisés ont un nom descriptif préfixé par _. Pylint considère les sections locales préfixées par _ comme inutilisées et les variables globales ou attributs préfixées par _ comme privées.

22
Vincent Povirk

Comme d'autres l'ont dit, le trait de soulignement (_) Est la norme. Mais si le soulignement est utilisé pour les traductions, je pense que le double soulignement est la meilleure alternative.

var, __, value = "VAR=value".partition('=')

Mieux que ceux-ci:

var, unused, value = "VAR=value".partition('=')

var, unused_del, value = "VAR=value".partition('=')

var, _del, value = "VAR=value".partition('=')

3
Rick Mohr

Si dans tout votre projet, vous ne faites cela qu'une seule fois ou très rarement par la fonction particulière, j'utiliserais la variante 1 si vous savez que gettext n'est pas un problème dans ce module, et sinon la variante 3.

D'un autre côté, si vous le faisiez beaucoup - et surtout si vous voulez à chaque fois un sous-ensemble différent des valeurs de retour (faire un wrapper pour renvoyez simplement celles qui vous tiennent à cœur), il pourrait être utile d'écrire un wrapper qui place les résultats dans un nommé Tuple , ou une instance d'une autre classe descriptive, qui vous permettrait de faire:

bar = foo()

Et puis travaillez avec bar.a, bar.b et bar.c.

3
lvc

Je ne suis pas un programmeur Python, mais pour moi, la troisième variante est la plus logique.

Dans la variante 3, vous êtes absolument clair sur les valeurs qui vous intéressent. Dans les variantes 1 et 2, vous réattribuez les valeurs aux variables et, par conséquent, elles peuvent être utilisées. Vous les avez peut-être nommés obscurément, mais une mauvaise dénomination n'est pas vraiment une solution à un problème.

Outre la clarté, pourquoi voudriez-vous affecter des valeurs inutilisées à un emplacement en mémoire (comme dans les variantes 1 et 2)? Ce serait une mauvaise solution en termes de gestion de la mémoire.

1
Craige