pythonアクセサリーの詳細
6325 ワード
前言
この文章はpython 3の中の装飾器についてのいくつかの認識を書いて、知識のレベルを高めるつもりです.
1アクセサリーは何ですか
装飾器は本質的にPython関数/クラスであり、他の関数/クラスがコード修正を必要とせずに追加機能を追加することができ、装飾器の戻り値も関数/クラスオブジェクトである.ログの挿入、パフォーマンステスト、パーミッションチェックなどのシーンでは、このような問題を解決するために、装飾器が優れた設計であるなど、断面的なニーズのあるシーンでよく使用されます.装飾器があれば,関数機能自体に関係のないコードを装飾器に多重化することができる.要約すると、装飾器の役割は、既存のオブジェクトに追加の機能を追加することです.
2シンプルなデコレーション(@記号は使用しない)
簡単なアクセサリーの例ですlog_appendはdirectを飾るprint,この書き方は任意のパラメータのdirect_をサポートするprintは、任意のパラメータの装飾関数log_もサポートします.append
3用@記号
@記号を利用して、コードの読解性を高めることができて、私達は@の方式で上のコードを書き換えます
4装飾器関数パラメータを伝達し、装飾器の利便性を体現する
インタフェース強制チェックのルールが不定の場合、1つの関数はnameを強制チェックし、もう1つの強制チェックnamesフィールドは、後でキーなどの他のフィールドを強制チェックし、log_を書き換える可能性があります.appendは便利です次のコードはまったく変更されませんdirect_printビジネスロジックの場合、検証ロジックが書き換えられdirect_に多重化されるprint_namesメソッド
5 functools.wraps保持関数情報
functoolsは使用しません.wrapsはdirect_を使用するなどdocstring、nameなどの関数メタ情報を失う可能性があります.print_names.nameはwrapperを返します.これは使用に影響します.だからfunctoolsが必要です.wraps.加入方式は簡単で、再装飾関数がfuncに伝わるところに@wrapsを加える
6呼び出し順序
pythonは多重装飾をサポートしており、使用方法は1つ1つ@で書かれており、その実行順序は外から中へ、最初に最外層の装飾器を呼び出し、最後に最下層の装飾器を呼び出して上のコードに印刷時間の装飾関数print_を加えるtime、direct_print先装print_time,direct_print_names後飾り、実はdirect_print効果は等しい
direct_print_names効果は等しい
全体コードは以下の通りです.
締めくくり
この文章を見て、pythonの装飾器はほとんど悪くないでしょう、よく勉強して、毎日向上します^^;
この文章はpython 3の中の装飾器についてのいくつかの認識を書いて、知識のレベルを高めるつもりです.
1アクセサリーは何ですか
装飾器は本質的にPython関数/クラスであり、他の関数/クラスがコード修正を必要とせずに追加機能を追加することができ、装飾器の戻り値も関数/クラスオブジェクトである.ログの挿入、パフォーマンステスト、パーミッションチェックなどのシーンでは、このような問題を解決するために、装飾器が優れた設計であるなど、断面的なニーズのあるシーンでよく使用されます.装飾器があれば,関数機能自体に関係のないコードを装飾器に多重化することができる.要約すると、装飾器の役割は、既存のオブジェクトに追加の機能を追加することです.
2シンプルなデコレーション(@記号は使用しない)
簡単なアクセサリーの例ですlog_appendはdirectを飾るprint,この書き方は任意のパラメータのdirect_をサポートするprintは、任意のパラメータの装飾関数log_もサポートします.append
def log_append():
def decorator(func):
def wrapper(**kwargs):
if "name" in kwargs:
print("check name %s" % (kwargs.get("name")))
else:
print("check name fail" )
return
return func(**kwargs)
return wrapper
return decorator
def direct_print(**kwargs):
print("print name is %s"% (kwargs.get("name")))
fun_decoratored=log_append()(direct_print)
fun_decoratored(names="111")
fun_decoratored(name="111")
print(fun_decoratored)
direct_print(name="111")
3用@記号
@記号を利用して、コードの読解性を高めることができて、私達は@の方式で上のコードを書き換えます
def log_append():
def decorator(func):
def wrapper(**kwargs):
if "name" in kwargs:
print("check name %s" % (kwargs.get("name")))
else:
print("check name fail" )
return
return func(**kwargs)
return wrapper
return decorator
@log_append()
def direct_print(**kwargs):
print("print name is %s"% (kwargs.get("name")))
direct_print(name="111")
direct_print(names="111")
4装飾器関数パラメータを伝達し、装飾器の利便性を体現する
インタフェース強制チェックのルールが不定の場合、1つの関数はnameを強制チェックし、もう1つの強制チェックnamesフィールドは、後でキーなどの他のフィールドを強制チェックし、log_を書き換える可能性があります.appendは便利です次のコードはまったく変更されませんdirect_printビジネスロジックの場合、検証ロジックが書き換えられdirect_に多重化されるprint_namesメソッド
from collections import Iterable
def log_append(au_keys=[]):
def decorator(func):
def wrapper(**kwargs):
if not isinstance(au_keys,Iterable):
raise Exception("error au_keys,should be Iterable str")
for check_key in au_keys:
if check_key in kwargs:
print("check %s %s" % (check_key,kwargs.get(check_key)))
else:
print("check %s fail
"% (check_key))
return
return func(**kwargs)
return wrapper
return decorator
@log_append(["name"])
def direct_print(**kwargs):
print("print name is %s
"% (kwargs.get("name")))
@log_append(["names"])
def direct_print_names(**kwargs):
print("print names is %s
"% (kwargs.get("names")))
direct_print(name="111")
direct_print(names="111")
direct_print_names(name="111")
direct_print_names(names="111")
5 functools.wraps保持関数情報
functoolsは使用しません.wrapsはdirect_を使用するなどdocstring、nameなどの関数メタ情報を失う可能性があります.print_names.nameはwrapperを返します.これは使用に影響します.だからfunctoolsが必要です.wraps.加入方式は簡単で、再装飾関数がfuncに伝わるところに@wrapsを加える
from collections import Iterable
from functools import wraps
def log_append(au_keys=[]):
def decorator(func):
@wraps(func)
def wrapper(**kwargs):
print()
if not isinstance(au_keys,Iterable):
raise Exception("error au_keys,should be Iterable str")
for check_key in au_keys:
if check_key in kwargs:
print("check %s %s" % (check_key,kwargs.get(check_key)))
else:
print("check %s fail
"% (check_key))
return
return func(**kwargs)
return wrapper
return decorator
@log_append(["name"])
def direct_print(**kwargs):
print("print name is %s
"% (kwargs.get("name")))
@log_append(["names"])
def direct_print_names(**kwargs):
print("print names is %s
"% (kwargs.get("names")))
direct_print(name="111")
direct_print(names="111")
direct_print_names(name="111")
direct_print_names(names="111")
print(direct_print.__name__)
6呼び出し順序
pythonは多重装飾をサポートしており、使用方法は1つ1つ@で書かれており、その実行順序は外から中へ、最初に最外層の装飾器を呼び出し、最後に最下層の装飾器を呼び出して上のコードに印刷時間の装飾関数print_を加えるtime、direct_print先装print_time,direct_print_names後飾り、実はdirect_print効果は等しい
print_time(log_append(["name"])(direct_print))
direct_print_names効果は等しい
log_append(["_names"])(print_time(direct_print))
全体コードは以下の通りです.
from collections import Iterable
from functools import wraps
import time
def log_append(au_keys=[]):
def decorator(func):
@wraps(func)
def wrapper(**kwargs):
print()
if not isinstance(au_keys,Iterable):
raise Exception("error au_keys,should be Iterable str")
for check_key in au_keys:
if check_key in kwargs:
print("check %s %s" % (check_key,kwargs.get(check_key)))
else:
print("check %s fail
"% (check_key))
return
return func(**kwargs)
return wrapper
return decorator
def print_time(func):
@wraps(func)
def wrapper(**kwargs):
print("time is %s"%(time.strftime("%Y-%m-%d %H:%M;%S",time.localtime())))
return func(**kwargs)
return wrapper
@print_time
@log_append(["name"])
def direct_print(**kwargs):
print("print name is %s
"% (kwargs.get("name")))
@log_append(["names"])
@print_time
def direct_print_names(**kwargs):
print("print names is %s
"% (kwargs.get("names")))
direct_print(name="111")
direct_print(names="111")
direct_print_names(name="111")
direct_print_names(names="111")
print(direct_print.__name__)
締めくくり
この文章を見て、pythonの装飾器はほとんど悪くないでしょう、よく勉強して、毎日向上します^^;