ホームページ > バックエンド開発 > Python チュートリアル > Python のデコレータとは何ですか? Python のデコレータの概要

Python のデコレータとは何ですか? Python のデコレータの概要

不言
リリース: 2018-09-13 16:50:24
オリジナル
2923 人が閲覧しました

この記事では、Python のデコレーターとは何なのかについて説明します。 Python でのデコレータの紹介は一定の参考になるので、困っている友人は参考にしていただければ幸いです。

1. デコレーターとは何ですか?

デコレーター、デコレーターは、本質的には、コードを変更せずに他の関数が機能できるようにする Python 関数です。 、デコレータの戻り値も関数オブジェクトです。

デコレータは、コア コードを変更することなく、コア コード部分の機能を強化します。たとえば、ログ、権限の検証、トランザクション処理、その他のシナリオを関数の前に挿入します。
また、関数関数とは関係のない大量の同様のコードを抽出して再利用できます。

2. 初期の実装: デコレータではないデコレータ

  • Python の関数もオブジェクトとみなされ、それに割り当てることができます。変数 を指定し、その変数を介して関数を呼び出します。

例:

def foo():
   print("2017-06-08")
f = foo    # 将函数赋值给变量,f为函数对象
f()
# 返回结果:
2017-06-08
ログイン後にコピー

3. 構文 Sugar@ 単純なデコレータを実装する

ここで、foo を拡張したいとします。 () 関数呼び出しの前にログを出力するなどの機能。ただし、foo() 関数の定義は変更したくありません。コードの実行中に機能を動的に追加するこの方法は、「デコレーター」と呼ばれます。
は次のとおりです。

def testfunc(func):
    print('testfunc')
    def wrapper():
        print("%s %s() called" %(time.ctime(),func.__name__))
        return func()
    return wrapper
@testfunc 
def foo():
    print('foo1()')

foo()  # 相当于执行testfunc(foo) ->wrapper(foo) -> foo()
ログイン後にコピー

実行結果:

testfunc
Wed Sep 12 15:01:13 2018 foo() called
foo1()
ログイン後にコピー

説明: foo() を実行する前に、まず testfunc(foo) を実行します。次に、wrapper() を実行し、戻り時に foo() 自体を呼び出します。

4. 特定の種類のパラメータを受け取るデコレータ

  • デコレータはパラメータを受け取ることができます。デコレータによって返された関数が呼び出されるとき、それはラッピング関数が呼び出され、パラメータがラッピング関数に渡され、ラッピング関数がパラメータを装飾関数に渡します。

は次のとおりです:

def testfunc_with_args(func):
    def wrapper_argus(arg1, arg2):
        print("I got args! Look:", arg1, arg2)
        func(arg1, arg2)
    return wrapper_argus
@testfunc_with_args
def full_name(first_name, last_name):  # 带参数,将参数传给被装饰的函数
    print("My name is", first_name, last_name)

full_name("Peter", "Venkman")  # 调用
ログイン後にコピー

実行結果:

I got args! Look: Peter Venkman
My name is Peter Venkman
ログイン後にコピー

5. 不定パラメータを持つデコレータ

デコレータを呼び出す必要がある関数が複数あるが、関数のパラメータが異なる場合、どのように実装すればよいでしょうか? 1 つのデコレータに 1 つの関数が対応することはできません。現時点では、可変パラメータを持つデコレーターを使用して実装できます。
は次のとおりです:

def log(func):
    def wrapper(*args,**kwargs):        # 可接受各种参数
        print('call %s():'% func.__name__)
        return func(*args,**kwargs)     # 返回一个函数
    return wrapper                      # 装饰器返回一个函数,进入到wrapper()

@log      # @log放到now()的定义处,相当于执行语句:now = log(now)
def now_1(a,b):
    print('now()1:a+b = ',a+b)
@log
def now_2(a,b,c):
    print('now_2():a+b+c = ',a+b+c)

now_1(1,2)
now_2(1,2,3)
ログイン後にコピー

実行してください~

6. 複数のデコレータ

関数に複数の関数を追加したい場合は、次のようにすることができます。マルチレイヤー デコレータの使用を検討してください。ただし、デコレータの実行順序に注意する必要があります。
クリを与える:

# 注意代码的执行顺序
def deco_1(func):
    print('------111111------')
    def wrapper(*args,**kwargs):    # 包裹函数,参数与原函数的参数一致
        print('start: this is deco_1.')
        func(*args,**kwargs)
        print('end: deco_1.')
    return wrapper  # 返回值是一个包裹函数
def deco_2(func):
    print('------222222------')
    def wrapper(*args,**kwargs):
        print('start: this is deco_2.')
        func(*args,**kwargs)
        print('end: deco_2.')
    return wrapper

@deco_1
@deco_2
def now_1(a,b):
    print('now()1:a+b = ',a+b)

now_1(1,2)
ログイン後にコピー

実行結果:

# 结果,注意执行顺序:
------222222------
------111111------
start: this is deco_1.
start: this is deco_2.
now()1:a+b =  3
end: deco_2.
end: deco_1.
ログイン後にコピー

7. デコレーター自体はパラメーターを受け取ります

装飾関数パラメータ。デコレータ自体もパラメータを取ることができます。

def logging(level):
    def wrapper(func):
        def inner_wrapper(*args, **kwargs):
            print("[{level}]: enter function {func}()".format(level=level, func=func.__name__))
            return func(*args, **kwargs)
        return inner_wrapper
    return wrapper
    
@logging(level='INFO')
def say(something):
    print("say {}!".format(something))

@logging(level='DEBUG')
def do(something):
    print("do {}...".format(something))

say('hello')
do("my work")
ログイン後にコピー

実行結果:

# 执行结果:
[INFO]: enter function say()
say hello!
[DEBUG]: enter function do()
do my work...
ログイン後にコピー

関連する推奨事項:

Python のデコレーターの詳細な説明

Python のさまざまなデコレータの詳細な説明

以上がPython のデコレータとは何ですか? Python のデコレータの概要の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート