Is "*_" an acceptable way to ignore arguments in Python?

_ is just a variable like any other, but by convention it means that you don't intend to use that value, just declare and forget it.

[OrderedSet() for _ in xrange(n)]

builds a list of n empty ordered sets. _ is the index, but is unused; _ is commonly used as required, but unused, variable name (not only in Python). This is just a tricky Python idiom because there is no built-in syntax to do this.

It's not uncommon to see this in other languages (where _ is a valid identifier). _ often means a variable one's not interested in the value of, but which is needed for syntactic reasons.

Note that _(...) as a macro call has another conventional meaning, which comes from gettext, where one uses _("string literal") to indicate a string that needs localization.

A thread to read from ActivesState

I can not say about any problems, Python doesn't use it internally, it's just a variable, it is us who have to be careful.


Regarding the syntax of * and **: The names *args and **kwargs are only by convention, but there's no need not to use them.

def my_callbacK_handler(a, b, *_):
    ...

So what I understand if I see this function in your code by _ idiom, that this function only uses a and b arguments in its working and will ignore others.

As you state: "*_ to express no interest in any further arguments".


*_ means multiple placeholders,just like you write def my_callbacK_handler(a, b, _,_,_....,_): and will create a variable named _ which is a list of the extra arguments

It has two advantage:

  1. It can handle the case where there is no extra argument
def f(): 
   return 1,2,3 

def g(): 
   return 1,2

def h(): 
   return 1,2,3,4

_ as a placeholder can only deal with exactly one value

x,y,_ = g() # ValueError: not enough values to unpack (expected 3, got 2)

x,y,_ = h() # ValueError: too many values to unpack (expected 3)

whereas *_ can deal with any amount of values

x,y,*_ = g()                                                                                                                  

print(_)                                                                                                                      
[]

x,y,*_ = h()                                                                                                                  

print(_)                                                                                                                      
[3, 4]

One word: Prefer *_ for more robust code.