Подтвердить что ты не робот

Как передать переменную в декораторе для аргумента функции в украшенной функции?

Я изучаю Python. Надеюсь, кто-то указывает мне на правильный путь.
Вот что я хотел бы сделать ниже:

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

Любая идея? Спасибо заранее.

4b9b3361

Ответ 1

Вы не можете передать его как свое имя, но вы можете добавить его к ключевым словам.

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'])

В качестве альтернативы вы можете назвать свой собственный аргумент:

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)

Метод класса:

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)

Ответ 2

Если вы хотите, чтобы аргумент был "необязательно введен", только в том случае, если функция фактически принимает его, используйте что-то вроде этого:

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."