Python 0502-アクセサリー
24794 ワード
装飾品の要件
def add(x,y):
return x+y
#
def add(x, y):
print("calladd, x+y") #
return x+y
ニーズの改善、ビジネス機能の分離
def add(x, y):
return x + y
def logger(fn):
print('begin') #
x = fn(4, 5)
print('end') #
return x
print(logger(add))
----------------------------
begin
end
9
ニーズの改善、導入
def add(x, y):
return x + y
def logger(fn, *args, **kwargs):
print('begin')
x = fn(*args, **kwargs)
print('end')
return x
print(logger(add, 4, y=5))
--------------------------------
begin
end
9
需要を改善し、コリー化
def add(x, y):
return x + y
def logger(fn):
def _logger(*args, **kwargs):
print('begin')
x = fn(*args, **kwargs)
print('end')
return x
return _logger
print(logger(add)(5, y=50))
#
add = logger(add) # _logger, = ,add1 ,fn
print(add(x=5, y=10)) # logger(add, x=5, y=10)
装飾器文法糖
def logger(fn):
def wrapper(*args, **kwargs):
print('begin')
x = fn(*args, **kwargs)
print('end')
return x
return wrapper
@logger # add = logger(add)
def add(x, y):
return x + y
print(add(45, 40))
アクセサリーの説明
コードデモ
import datetime
import time
def logger(fn):
def wrap(*args, **kwargs):
# before
print("args={}, kwargs={}".format(args,kwargs))
start = datetime.datetime.now()
ret = fn(*args, **kwargs)
# after
duration = datetime.datetime.now() - start
print("function{} took {}s."
.format(fn.__name__, duration.total_seconds()))
return ret
return wrap
@logger # add = logger(add)
def add(x, y):
print("===call add===========")
time.sleep(2)
return x + y
print(add(4, y=7))
---------------------------------
args=(4,), kwargs={'y': 7}
===call add===========
function add took 2.016632s. # : add
11
どのように装飾器を理解しますか?
に縁を付ける
装飾関数
ガラス
プリアンブル機能の強化
絵をかく
エンハンス関数
これがコア
バックプレート
バックグラウンド機能の強化
ドキュメント文字列
def add(x, y):
"""This is a function of addition"""
a = x + y
return x + y
print("name={}
doc={}".format(add.__name__, add.__doc__))
print("====================")
print(help(add))
---------------------------------------------------------
name=add
doc=This is a function of addition
====================
Help on function add in module __main__:
add(x, y)
This is a function of addition
None
アクセサリー副作用
def logger(fn):
def wrapper(*args, **kwargs):
"""I am wrapper"""
print("begin")
x = fn(*args, **kwargs)
print("end")
return x
return wrapper
@logger # add = logger(add)
def add(x, y):
"""This is a function for add"""
return x + y
print("name={}
doc={}".format(add.__name__, add.__doc__))
-------------------------------------------
name=wrapper
doc=I am wrapper
パッケージ関数のプロパティ
def copy_properties(src, dst):
# ==copy==> ( )
dst.__name__ = src.__name__
dst.__doc__ = src.__doc__
def logger(fn):
def wrapper(*args, **kwargs):
"""I am wrapper"""
print("begin")
x = fn(*args, **kwargs)
print("end")
return x
copy_properties(fn, wrapper) # fn src,wrapper dst
return wrapper
@logger
def add(x, y):
"""This is a function for add"""
return x + y
print("name={}
doc={}".format(add.__name__, add.__doc__))
-------------------------------------
name=add
doc=This is a function for add
パッケージ関数のプロパティの説明
ほうそうかんすうコリーか
def copy_properties(src): #
def _copy(dst):
# ==copy==>
dst.__name__ = src.__name__
dst.__doc__ = src.__doc__
return dst
return _copy
def logger(fn):
@copy_properties(fn) # wrapper = copy_properties(fn, wrapper)
def wrapper(*args, **kwargs):
"""I am wrapper"""
print("begin")
x = fn(*args, **kwargs)
print("end")
return x
return wrapper
@logger # add = logger(add)
def add(x, y):
"""This is a function for add"""
return x + y
print("name={}
doc={}".format(add.__name__, add.__doc__))
---------------------------------------------
name=add
doc=This is a function for add
パラメトリック装飾
import datetime
import time
def copy_properties(src): #
def _copy(dst):
# ==copy==>
dst.__name__ = src.__name__
dst.__doc__ = src.__doc__
return dst
return _copy
def logger(duration):
def _logger(fn):
@copy_properties(fn) # wrapper = copy_properties(fn, wrapper)
def wrapper(*args, **kwargs):
"""I am wrapper"""
start = datetime.datetime.now()
x = fn(*args, **kwargs)
delta = (datetime.datetime.now()-start).total_seconds()
print('so slow') if delta > duration else print('so fast')
return x
return wrapper
return _logger
@logger(5) # add = logger(5)(add)
def add(x, y):
"""This is a function for add"""
time.sleep(3)
return x + y
print(add(5, 6))
-----------------------------------------
so fast
11
アクセサリー付きまとめ
アクセサリ付きフレキシブル制御
import datetime
import time
def copy_properties(src): #
def _copy(dst):
# ==copy==>
dst.__name__ = src.__name__
dst.__doc__ = src.__doc__
return dst
return _copy
def logger(duration,
func=lambda name,
duration:print("{} took {}s".format(name, duration))):
def _logger(fn):
@copy_properties(fn) # wrapper = copy_properties(fn, wrapper)
def wrapper(*args, **kwargs):
"""I am wrapper"""
start = datetime.datetime.now()
x = fn(*args, **kwargs)
delta = (datetime.datetime.now()-start).total_seconds()
if delta > duration:
func(fn.__name__, duration)
return x
return wrapper
return _logger
@logger(2) # add = logger(2)(add)
def add(x, y):
"""This is a function for add"""
time.sleep(3)
return x + y
print(add(5, 6))
--------------------------------------
add took 2s
11
functoolsモジュール
コードデモ
import datetime, time, functools
def logger(duration,
func=lambda name,
duration:print("{} took {}s".format(name, duration))):
def _logger(fn):
def wrapper(*args, **kwargs):
"""I am wrapper"""
start = datetime.datetime.now()
x = fn(*args, **kwargs)
delta = (datetime.datetime.now()-start).total_seconds()
if delta > duration:
func(fn.__name__, duration)
return x
return functools.update_wrapper(wrapper, fn)
# (wrapper, fn),functools.update_wrapper(wrapper, wrapped)wrapper 、 ,wrapped 、
return _logger
@logger(2) # add = logger(2)(add) # logger(2) => _logger add=_logger(add)
def add(x, y):
"""This is a function for add"""
time.sleep(1)
return x + y
print(add(5, 6), add.__name__, add.__wrapped__, add.__dict__, sep='
')
-------------------------------------
11
add
0x0000024974109158>
{'__wrapped__': 0x0000024974109158>}
functoolsモジュール@
コード最適化
import datetime, time, functools
def logger(duration,
func=lambda name,
duration:print("{} took {}s".format(name, duration))):
def _logger(fn):
@functools.wraps(fn) # wrapper = functools.wraps(fn, wrapper)
# fn?@functools.wraps(wrapped), wrapped
def wrapper(*args, **kwargs):
"""I am wrapper"""
start = datetime.datetime.now()
x = fn(*args, **kwargs)
delta = (datetime.datetime.now()-start).total_seconds()
if delta > duration:
func(fn.__name__, duration)
return x
return wrapper
return _logger
@logger(2) # add = logger(2)(add)
def add(x, y):
"""This is a function for add"""
time.sleep(1)
return x + y
print(add(5, 6), add.__name__, add.__wrapped__, add.__dict__, sep='
')
---------------------------------
11
add
0x000001F674779158>
{'__wrapped__': 0x000001F674779158>}