Join us and get access to hundreds of tutorials and a community of expert Pythonistas.

Unlock This Lesson

This lesson is for members only. Join us and get access to hundreds of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Hint: You can adjust the default video playback speed in your account settings.
Hint: You can set the default subtitles language in your account settings.
Sorry! Looks like there’s an issue with video playback 🙁 This might be due to a temporary outage or because of a configuration issue with your browser. Please see our video player troubleshooting guide to resolve the issue.

Decorating Functions With Arguments

This lesson will show you how to use the *args and **kwargs syntax to modify decorators to accept any number of arguments.

Vanam on May 8, 2019

I think in the example, we can have the wrapper to accept only args, def wrapper(*args): With this also, we can pass with or without arguments while calling the decorated function (Please correct me if i am wrong)

Chris Bailey RP Team on May 8, 2019

Hi Vanam, You are correct. If you don’t think your wrapped functions will do anything with keyword arguments, then you could use (*args) only. The method shown will allow either type, and will not have issues if you only use arguments and not keyword arguments (or vice versa). It would, as a tool, be more flexible.

grzegorzmalinowski on Jan. 8, 2020

Is it possibly inside the wrapper to pass new arg vaalue to the function to be decorated?

Chris Bailey RP Team on Jan. 8, 2020

Hi @grzegorzmalinowski, I’m not sure I completely understand your question. When you are calling the decorated function as in the example, you are passing arg values to the function, or not if desired. You are providing the argument at the time of calling the function, which is one interpretation of “new”. It is possible to have structured the decorator to handle the arguments or keyword arguments in unique or separate ways also. Meaning do one thing with arguments and another with the keyword arguments. But I don’t think I’m catching your meaning.

grzegorzmalinowski on Jan. 8, 2020

Hi Chris, thank you for the answer. Since I’ve just started my journey with decorators, it might be that I was imprecise in fact. Please see my code. I’d like to change alpha (from predefined scalar to array/or any new value).

@opt_alpha
def update_weights(gradient_type='GD'):

    def MSE_GD(aug_data, response, weights, prediction, alpha=learning_rate):
        if np.ndim(alpha) != 0:
            alpha = alpha[:,np.newaxis]

        gradient = 2/response.size*((prediction - response)@aug_data)
        direction = -1*gradient
        weights = weights + alpha*direction
        return weights

    if gradient_type == 'GD':
        return MSE_GD
def opt_alpha(function):
    alpha = np.array([0,1,2])
    def weights_wrapper(*args, **kwargs):
        result = function(*args, **kwargs)
        return result
    return weights_wrapper

Chris Bailey RP Team on Jan. 9, 2020

Hi @grzegorzmalinowski, I think you would need to add the alpha keyword argument to your decorator “result”, after **kwargs. Please excuse my simplifying your function.

def opt_alpha(function):
    alpha = [0,1,2]
    def weights_wrapper(*args, **kwargs):
        result = function(*args, **kwargs, alpha=alpha)
        return result
    return weights_wrapper

@opt_alpha
def print_alpha(response=25, weights="normal", alpha=0):
    print(alpha)
    print(response)
    print(weights)

When calling you would get.

>>> print_alpha()
[0, 1, 2]
25
normal

The alpha argument will be passed to the function. But to take this a bit further have you looked at the original article that Geir Arne wrote, that my course is based on? Primer on Python Decorators, there is a section on Decorators with Arguments. It discusses when “decorating” a function, you could add an argument to the decorator, which could be the direction you are looking for. I hope this helps.

Become a Member to join the conversation.