Python give *args default value

Question:

Inside my class I have:

def refresh(self, func = None, *args):
    if not func:
        return
    new_data = func(*args)
    self.set_text(new_data)

But I have 2 problems:

  1. What if func doesn’t take any parameters? Why can’t I do *args = None?
    like I want to do something like this:

    def refresh(self, func = None, *args = None):
        if not func:
            return
        if *args:
            new_data = func(*args)
        else:
            new_data = func() # func doesn't take any parameters
        self.set_text(new_data)
    
  2. When I try to run my code before the edits I get:

    TypeError: function takes 0 positional arguments but 1 were given

    Why is that?

Here is my main:

def hello_world():
    return 'hello'

tmp2 = LLabel('Hi There!')
tmp2.refresh(hello_world, None)
Asked By: Mathio

||

Answers:

None is an argument of NoneType. You can try it simply by running the hello_world function by itself.

def hello_world():
    return 'hello'
hello_world(None)

Which will result in the following error: TypeError: hello_world() takes 0 positional arguments but 1 was given.

Hence run the refresh method, with only one argument – the function you want to pass in:

def hello_world():
    return 'hello'
tmp2 = LLabel('Hi There!')
tmp2.refresh(hello_world)

Therefore the original refresh method can stay the same:

def refresh(self, func = None, *args):
    if not func:
        return
    new_data = func(*args)
    self.set_text(new_data)
Answered By: CodeKorn

*args is of type tuple.

If your function doesn’t take parameters, that means you have an empty tuple args. And an empty tuple is a falsy value in Python.

So your function can look like this:

def refresh(self, func = None, *args):
    if not func:
        return
    if args:  # evaluates to True if not empty
        new_data = func(*args)
    else:
        new_data = func() # func doesn't take any parameters
    self.set_text(new_data)

The unpacking operator * is not needed in the if condition. It is actually a SyntaxError.

If you now call your refresh method, passing a function that doesn’t take any parameters, you just need to pass the function to the method:

def hello_world():
    return 'hello'

tmp2 = LLabel('Hi There!')
tmp2.refresh(hello_world)
Answered By: Wolric

You get the error "takes 0 positional arguments but 1 were given" because here

tmp2.refresh(hello_world, None)

the original implementation of refresh will not pass no argument to hello_world, but one argument, namely None.

Instead, just don’t provide any further arguments to refresh:

tmp2.refresh(hello_world)

Then, inside refresh, args will be an empty tuple and func(*args) will be equivalent to func().

The alternative implementation of refresh, which you have attempted to use, is not necessary.

Answered By: mkrieger1

In the call to refresh, you can just omit any additional arguments:

tmp2.refresh(hello_world)

This will cause the args variable within the function to be set an empty tuple, so the call to fn results in an empty argument list.

Answered By: Jamie Doornbos