web-dev-qa-db-ja.com

デコレータの変数をデコレートされた関数の関数の引数に渡すにはどうすればよいですか?

私は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

何か案が?前もって感謝します。

35
Japboy

独自の名前として渡すことはできませんが、キーワードに追加することはできます。

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)
52
Tor Valamo

引数を「オプションで挿入」したい場合は、関数が実際にそれを受け取る場合にのみ、次のようなものを使用します。

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