Existe-t-il un style de codage recommandé / généralement accepté pour gérer les situations où une fonction retourne 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 changer - écrire un wrapper autour l'appel est probablement un peu exagéré…)? Au lieu de faire
a, b, c = foo()
et ensuite ne pas utiliser b
and c
, laquelle des variantes suivantes devrait être préférée (ou y en a-t-il une autre?):
Variante 1 (soulignement)
a, _, _ = foo()
(qui est très clair et simple mais qui pourrait entrer en conflit avec _ = gettext.gettext
de nombreuses applications utilisant 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 les ()[0]
looks non pythoniques…)
la source
a, b = foo()[0:2]
cela fonctionnerait? Si oui: oui, c'est le cas :)a, *_ = foo()
supprimera toutes les valeurs sauf la première.Réponses:
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
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
ouunused
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 utilisedummy
généreusement et qui s'est également infiltrée 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:
la source
Pylint m'a donné l'habitude de le faire de cette façon:
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.
la source
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
gettext
que ce module ne pose pas de problème, et sinon la variante 3.D'un autre côté, si vous faisiez beaucoup cela - et surtout si chaque fois que vous voulez un sous-ensemble différent des valeurs de retour (faire un wrapper pour ne renvoyer que celles qui vous tiennent à cœur), il pourrait être avantageux d'écrire un wrapper qui place les résultats dans un tuple nommé , ou une instance d'une autre classe descriptive, qui vous permettrait de faire:
Et puis travailler avec
bar.a
,bar.b
etbar.c
.la source
Comme d'autres l'ont dit, le 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('=')
la source
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.
la source
Voici une règle générale: si seulement 1 des valeurs retournées est utilisée, pourquoi ne pas simplement retourner cette 1 valeur? Dans le cas où le drapeau est appelé à partir de plusieurs endroits, conservez un drapeau pour le même et retournez les valeurs selon le drapeau.
MODIFIER:
Dans le cas où j'étais dans votre situation et que je n'avais pas écrit la fonction, je choisirais peut-être la variante 2. Je garderais les noms fictifs là-bas afin que les paramètres puissent être utilisés en cas de besoin. Découper une liste aura un peu de frais généraux. Vous pouvez peut-être épargner quelques octets pour recevoir les données indésirables.
la source
%timeit a, _, _ = foo()
rapport à ce%timeit a = foo()[0]
qui a donné lieu à 123ns par rapport à 109ns, à savoir le découpage semble être effectivement plus rapide que la valeur du déballage. Ou aviez-vous une situation particulière en tête?