_
has 3 main conventional uses in Python:
- To hold the result of the last executed expression in an interactive interpreter session (see docs). This precedent was set by the standard CPython interpreter, and other interpreters have followed suit
- For translation lookup in i18n (see the gettext documentation for example), as in code like
raise forms.ValidationError(_("Please enter a correct username"))
- As a general purpose “throwaway” variable name:
- To indicate that part of a function result is being deliberately ignored (Conceptually, it is being discarded.), as in code like:
label, has_label, _ = text.partition(':')
- As part of a function definition (using either
def
orlambda
), where the signature is fixed (e.g. by a callback or parent class API), but this particular function implementation doesn’t need all of the parameters, as in code like:def callback(_): return True
[For a long time this answer didn’t list this use case, but it came up often enough, as noted here, to be worth listing explicitly.]
_
as a throwaway variable in any code block that also uses it for i18n translation (many folks prefer a double-underscore,__
, as their throwaway variable for exactly this reason). Linters often recognize this use case. For exampleyear, month, day = date()
will raise a lint warning ifday
is not used later in the code. The fix, ifday
is truly not needed, is to writeyear, month, _ = date()
. Same with lambda functions,lambda arg: 1.0
creates a function requiring one argument but not using it, which will be caught by lint. The fix is to writelambda _: 1.0
. An unused variable is often hiding a bug/typo (e.g. setday
but usedya
in the next line). The pattern matching feature added in Python 3.10 elevated this usage from “convention” to “language syntax” wherematch
statements are concerned: in match cases,_
is a wildcard pattern, and the runtime doesn’t even bind a value to the symbol in that case. For other use cases, remember that_
is still a valid variable name, and hence will still keep objects alive. In cases where this is undesirable (e.g. to release memory or external resources) an explicitdel name
call will both satisfy linters that the name is being used, and promptly clear the reference to the object. - To indicate that part of a function result is being deliberately ignored (Conceptually, it is being discarded.), as in code like: