Frerich Raabe
Frerich Raabe

Reputation: 94309

How can I denote unused function arguments?

When "deconstructing" a tuple, I can use _ to denote tuple elements I'm not interested in, e.g.

>>> a,_,_ = (1,2,3)
>>> a
1

Using Python 2.x, how can I express the same with function arguments? I tried to use underscores:

>>> def f(a,_,_): return a
...
  File "<stdin>", line 1
SyntaxError: duplicate argument '_' in function definition

I also tried to just omit the argument altogether:

>>> def f(a,,): return a
  File "<stdin>", line 1
    def f(a,,): return a
        ^
SyntaxError: invalid syntax

Is there another way to achieve the same?

Upvotes: 124

Views: 101352

Answers (8)

boxed
boxed

Reputation: 4417

A funny way I just thought of is to delete the variable:

def f(foo, unused1, unused2, unused3):
    del unused1, unused2, unused3
    return foo

This has numerous advantages:

  • The unused variable can still be used when calling the function both as a positional argument and as a keyword argument.
  • If you start to use it later, you can't since it's deleted, so there is less risk of mistakes.
  • It's standard python syntax.
  • PyCharm does the right thing! (As of 2020, PyCharm no longer does the right thing :( tracking this at https://youtrack.jetbrains.com/issue/PY-39889 )
  • PyLint won't complain and using del is the solution recommended in the PyLint manual.

Upvotes: 163

Paul Brown
Paul Brown

Reputation: 2403

The underscore is used for things we don't care about and the * in *args denotes a tuple of arguments. Therefore, we can use *_ to denote a tuple of things we don't care about:

def foo(bar, *_):
    return bar

Update with type-hints:

from typing import Any, Tuple

def foo(bar: Any, *_: Tuple[Any, ...]) -> Any:
    return bar

Upvotes: 99

Pankaj Rathi
Pankaj Rathi

Reputation: 75

You can use "*_" to use multiple unused arguments

def test(x, *_):
    return x

Upvotes: 1

Eric PASCUAL
Eric PASCUAL

Reputation: 219

In order to avoid "unused variable" inspection messages for unused *args and/or **kwargs, I replace args and kwargs by _ and __ :

def f(a, b, *_, **__):
    ...

In addition to remove messages, it clearly shows that you don't care about these arguments.

I can't say if it is a really universal solution, but it worked everywhere I've used it until now.

Upvotes: 5

Ronyis
Ronyis

Reputation: 1953

You can use '_' as prefix, so that pylint will ignore these parameters:

def f(a, _b, _c):

Upvotes: 76

Tomasz Gandor
Tomasz Gandor

Reputation: 8833

I think the accepted answer is bad, but it can still work, if you use what I should call "Perl way" of dealing with arguments (I don't know Perl really, but I quit trying to learn it after seeing the sub syntax, with manual argument unpacking):

Your function has 3 arguments - this is what it gets called with (Duck typing, remember?). So you get:

def funfun(a, b, c):
    return b * 2

2 unused parameters. But now, enter improved larsmans' approach:

def funfun(*args):
    return args[1] * 2

And there go the warnings...

However, I still enjoy more the boxed's way:

def funfun(a, b, c):
    del a, c
    return b * 2

It keeps the self-documenting quality of parameter names. They're a feature, not a bug.

But, the language itself doesn't force you there - you could also go the other way around, and just let all your function have the signature (*args, **kwargs), and do the argument parsing manually every time. Imagine the level of control that gives you. And no more exceptions when being called in a deprecated way after changing your "signature" (argument count and meaning). This is something worth considering ;)

Upvotes: 0

Maksym Polshcha
Maksym Polshcha

Reputation: 18358

If you have both args and keyword arg you should use

def f(a, *args, **kwargs):
    return a

Upvotes: 1

Fred Foo
Fred Foo

Reputation: 363547

Here's what I do with unused arguments:

def f(a, *unused):
    return a

Upvotes: 40

Related Questions