How to indicate multiple unused values in Python?

2019-06-17 01:21发布

问题:

Normally in Python, one should use an _ to indicate an argument is unused.

def example_basic(unused):
   pass

becomes

def example_basic(_):
   pass

Then if there are multiple unused arguments, multiple _s can't be used since they will conflict, so a *_ is used:

def example_multiple(unused1, unused2):
   pass

becomes

def example_multiple(*_):
   pass

Finally, what should be done if there are multiple non-adjacent arguments that go unused?

def example_non_adjacent(unused1, used, unused2):
    return used

Using multiple _s still does not work, and using *_ won't work since they're non-adjacent.

Note that I would very much prefer to change the API, but for the sake of this question let's assume that's not possible. Is there a way to indicate it's ignored without using something like # pylint: disable=unused-argument for PyLint or i-dont-know-what for PyCharm?

EDIT:

I posted an example where this is needed here

回答1:

I've seen codes using the following idiom;

def example_non_adjacent(_0, used, _1, _2, _3, also_used):
    ...

which I find nice if you truly have lots of unused variables.

That said, just because a variable is unused does not mean that the code is more readable if you leave out its proper name. This should only be done if you really think that hiding the variable names improve the readability and/or understanding of the code.



回答2:

Pylint (and most likely other readers of your code) will be as happy if you concatenate several underscores. Pylint won't complain about unused arguments if you do this:

def example_non_adjacent(_, used, __):
    return used

I agree with some commenters in which this is ugly and I would try to avoid it by all means.

Pylint (and most human readers, I guess) won't complain either if you add the prefix cb_ to your function names to convey the fact that they are callbacks and you have to receive some arguments even if you do not want to use them. This looks like a better solution to me.

def cb_example_non_adjacent(unused1, used, unused2):
    return used


回答3:

Just del them. It is lightning fast because of the way garbage collector works.

def test(test):
    del test

    print('I do not need test parameter here!')

If you are passing parameters with callback method then give them a proper name and del them. Do not denote them as unused.

This is an example callback function:

def handle(socket, address):
    del address  # del is as efficient as a newline ;-)

    stream = bytes()
    while True:
        chunk = socket.recv()
        if not chunk:
            break

        stream += chunk

    return stream

Pythonistas normally do not use _ underscore name for an argument is any case possible.
You may have misunderstood usage of _ underscore as a name for a non useful variable.

It is understandable to use _ for a variable name when we do not know how to call it and/or it will not get used:

# ignore variables when unpacking a tuple
def test():
    """some code here"""

    top = 10
    right = 10
    bottom = 40
    left = 10

    return top, right, bottom, left


# here we ignore right and left
top, _, bottom, _ = test()

# use top and bottom in your code


回答4:

I strongly agree with @jmd_dk on this one. Just because the function doesn't actually reference or modify an argument, it doesn't mean it isn't 'used'. After all, it has to be instantiated and explicitly passed to the function. The only justified use of underscores for variable names is when using for-loops and list comprehensions:

numbers = {_ for _ in range(10)}

for _ in numbers:
    print("Foo!")

But the fact that you need a solution like this means there's a design problem in your code.