How can I pass a variable in a decorator to function's argument in a decorated function?

PythonDecorator

Python Problem Overview


I am in progress to learn Python. Hopefully someone points me to correct way.
This is what I'd like to do below:

def decorate(function):
    def wrap_function(*args, **kwargs):
        str = 'Hello!'  # This is what I want
        return function(*args, **kwargs)
    return wrap_function

@decorate
def print_message():
    # I'd like to pass 'str' as mentioned above
    # to any functions' argument like below:
    print(str)  # 'str' is same as above

Any idea? Thanks in advance.

Python Solutions


Solution 1 - Python

You can't pass it as its own name, but you can add it to the keywords.

def decorate(function):
    def wrap_function(*args, **kwargs):
        kwargs['str'] = 'Hello!'
        return function(*args, **kwargs)
    return wrap_function

@decorate
def print_message(*args, **kwargs):
    print(kwargs['str'])

Alternatively you can name its own argument:

def decorate(function):
    def wrap_function(*args, **kwargs):
        str = 'Hello!'
        return function(str, *args, **kwargs)
    return wrap_function

@decorate
def print_message(str, *args, **kwargs):
    print(str)

Class method:

def decorate(function):
    def wrap_function(*args, **kwargs):
        str = 'Hello!'
        args.insert(1, str)
        return function(*args, **kwargs)
    return wrap_function

class Printer:
    @decorate
    def print_message(self, str, *args, **kwargs):
        print(str)

Solution 2 - Python

If you want the argument to be "optionally-injected", only in case the function actually takes it, use something like this:

import inspect

def decorate(func):
    def wrap_and_call(*args, **kwargs):
        if 'str' in inspect.getargspec(func).args:
            kwargs['str'] = 'Hello!'
        return func(*args, **kwargs)
    return wrap_and_call

@decorate
def func1(str):
    print "Works! - " + str

@decorate
def func2():
    print "Should work, also."

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJapboyView Question on Stackoverflow
Solution 1 - PythonTor ValamoView Answer on Stackoverflow
Solution 2 - PythonVladiusView Answer on Stackoverflow