Quelle est la signification de _
après for
dans ce code?
if tbh.bag:
n = 0
for _ in tbh.bag.atom_set():
n += 1
Quelle est la signification de _
après for
dans ce code?
if tbh.bag:
n = 0
for _ in tbh.bag.atom_set():
n += 1
_
a 3 utilisations conventionnelles principales en Python :
Pour contenir le résultat de la dernière expression exécutée dans une session interactive interpréteur (voir docs). Ce précédent a été établi par l'interpréteur standard CPython et d'autres interprètes ont suivi le mouvement
Pour la recherche de traduction en i18n (voir la gettext documentation par exemple), comme dans le code suivant
raise forms.ValidationError(_("Veuillez entrer un nom d'utilisateur correct"))
Comme un nom de variable "jetable" à usage général :
Pour indiquer qu'une partie du résultat d'une fonction est délibérément ignorée (Conceptuellement, elle est rejetée), comme dans le code suivant :
label, has_label, _ = text.partition(':')
Comme partie d'une définition de fonction (utilisant soit def
soit lambda
), où la signature est fixe (par exemple par un rappel ou une API de classe parent), mais cette implémentation de fonction particulière n'a pas besoin de tous les paramètres, comme dans le code suivant :
def rappel(_):
return True
[Pendant longtemps, cette réponse ne mentionnait pas ce cas d'utilisation, mais il est apparu assez souvent, comme indiqué ici, pour mériter d'être listé explicitement.]
Ce cas d'utilisation peut entrer en conflit avec le cas d'utilisation de recherche de traduction, il est donc nécessaire d'éviter d'utiliser _
comme nom de variable jetable dans tout bloc de code qui l'utilise également pour la traduction i18n (beaucoup de gens préfèrent un double tiret bas, __
, comme leur nom de variable jetable pour cette raison).
Les linter reconnaissent souvent ce cas d'utilisation. Par exemple, année, mois, jour = date()
générera un avertissement linter si jour
n'est pas utilisé plus tard dans le code. La solution, si jour
n'est vraiment pas nécessaire, est d'écrire année, mois, _ = date()
. De même avec les fonctions lambda, lambda arg: 1.0
crée une fonction nécessitant un argument mais ne l'utilisant pas, ce qui sera détecté par le linter. La solution est d'écrire lambda _: 1.0
. Une variable inutilisée cache souvent un bug/une faute de frappe (par exemple, définir jour
mais utiliser dya
à la ligne suivante).
La fonctionnalité de correspondance de motifs ajoutée dans Python 3.10 a élevé cette utilisation de "convention" à "syntaxe de langage" en ce qui concerne les déclarations match
: dans les cas de correspondance, _
est un motif générique, et l'exécution ne lie même pas une valeur au symbole dans ce cas.
Pour d'autres cas d'utilisation, n'oubliez pas que _
reste un nom de variable valide, et donc garde toujours des objets en vie. Dans les cas où cela est indésirable (par exemple pour libérer de la mémoire ou des ressources externes), un appel explicite del nom
satisfera à la fois les linters indiquant que le nom est utilisé, et effacera promptement la référence à l'objet.
Pouvez-vous expliquer comment cela fonctionne dans un appel de fonction, par exemple : raise forms.ValidationError(_("Veuillez entrer un nom d'utilisateur correct")). J'ai vu cela dans le code Django, et ce n'est pas clair ce qui se passe.
Ceci est l'utilisation 2 - par convention, _
est le nom utilisé pour la fonction qui effectue des recherches de traduction de chaînes pour l'internationalisation et la localisation. Je suis assez sûr que c'est la bibliothèque C gettext
qui a établi cette convention.
FWIW, j'ai personnellement commencé à utiliser __
(un double tiret bas) comme ma variable jetable générale pour éviter les conflits avec les deux premiers cas d'utilisation.
Souligné _
est considéré comme variable "Je m'en fiche" ou "jetable" en Python
L'interpréteur Python stocke la dernière valeur d'expression dans la variable spéciale appelée _
.
>>> 10
10
>>> _
10
>>> _ * 3
30
L'underscore _
est également utilisé pour ignorer des valeurs spécifiques. Si vous n'avez pas besoin des valeurs spécifiques ou si les valeurs ne sont pas utilisées, attribuez simplement les valeurs à l'underscore.
Ignorer une valeur lors du dépaquetage
x, _, y = (1, 2, 3)
>>> x
1
>>> y
3
Ignorer l'index
for _ in range(10):
faire_quelque_chose()
Il y a un troisième usage, qui est pour la fonction d'internationalisation _ ("Hello world!")
.
Au niveau du processeur, y a-t-il réellement une différence entre "for _ in range" et "for x in range" et ensuite ne pas utiliser x? Ou est-ce simplement pour la lisibilité humaine?
@iammax En utilisant le module dis
, j'ai trouvé qu'il n'y avait aucune différence dans le bytecode. Les avantages de la lisibilité humaine sont évidents, cependant.
Il existe 5 cas d'utilisation du tiret bas en Python.
Pour stocker la valeur de la dernière expression dans l'interpréteur.
Pour ignorer des valeurs spécifiques. (appelées "je m'en fiche")
Pour donner des significations et fonctions spéciales au nom des variables ou fonctions.
Pour utiliser comme fonctions 'internationalisation (i18n)' ou 'localisation (l10n)’.
Pour séparer les chiffres de la valeur littérale d'un nombre.
Ici se trouve un bel article avec des exemples de mingrammer.
Les numéros 3 et 5 ne s'appliquent pas vraiment à cette question. L'OP demande un simple soulignement en tant que nom autonome, mais le point 3 parle de l'utilisation de soulignements comme partie d'un plus grand nom, et le point 5 parle de son utilisation dans un sens littéral, pas en tant que nom. Je mentionne juste au cas où des nouveaux soient confus. Il pourrait être utile de modifier la réponse pour le clarifier.
En ce qui concerne le langage Python, _
n'a généralement pas de signification spéciale. C'est un identifiant valide tout comme _foo
, foo_
ou _f_o_o_
.
La seule exception concerne les instructions match
depuis Python 3.10 :
Dans un motif
case
au sein d'une instructionmatch
,_
est un mot-clé souple qui représente un joker. source
Autrement, toute signification particulière de _
est purement conventionnelle. Plusieurs cas sont courants :
Un nom fictif lorsque qu'une variable n'est pas destinée à être utilisée, mais qu'un nom est requis par la syntaxe/sémantique.
# itération en ignorant le contenu
sum(1 for _ in some_iterable)
# déballage en ignorant des éléments spécifiques
head, *_ = values
# fonction ignorant son argument
def callback(_): return True
Beaucoup de REPL/shells stockent le résultat de la dernière expression de niveau supérieur dans builtins._
.
L'identifiant spécial
_
est utilisé dans l'interpréteur interactif pour stocker le résultat de la dernière évaluation ; il est stocké dans le modulebuiltins
. Lorsque ce n'est pas en mode interactif,_
n'a pas de signification spéciale et n'est pas défini. [source]
En raison de la façon dont les noms sont recherchés, sauf s'ils sont occultés par une définition globale ou locale de _
, le simple _
fait référence à builtins._
.
>>> 42
42
>>> f'la dernière réponse est {_}'
'la dernière réponse est 42'
>>> _
'la dernière réponse est 42'
>>> _ = 4 # occulter ``builtins._`` avec ``_`` global
>>> 23
23
>>> _
4
Remarque : Certains shells comme ipython
n'assignent pas à builtins._
mais traitent _
de manière spéciale.
Dans le contexte de l'internationalisation et de la localisation, _
est utilisé comme un alias pour la fonction de traduction principale.
gettext.gettext(message)
Retourne la traduction localisée du message, basée sur le domaine, la langue et le répertoire de localisation global actuels. Cette fonction est généralement renommée en
_()
dans l'espace de noms local (voir exemples ci-dessous).
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
9 votes
Voir stackoverflow.com/questions/1739514/as-variable-name-in-python
7 votes
Pour votre cas, il serait plus propre d'utiliser soit
len(tbh.bag.atom_set())
(si la valeur retournée a une méthode__len__
) ousum(1 for _ in tbh.bag.atom_set())
0 votes
Dans
pylint
, une autre option pour les noms de variables bidons est un préfixe dedummy_
pour le nom de la variable. En utilisant ce préfixe avecpylint
, cela empêchepylint
d'émettre un avertissement. Vous pouvez également configurer le motif de variable bidon pourpylint
pour prendre en compte des choses comme__
.