1

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)
0

4 Answers 4

2

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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)

Comments

0

*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)

2 Comments

Thanks, but do I really need that if condition?
Like @mkrieger1 said, you don't need the if args condition, as nothing will be passed to func(*args) if args is empty. I did it just for completeness.
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.