序文
のようなデコレータで単一のディスパッチを使用していますfunctools.singledispatch
from functools import singledispatch
from typing import Any
@singledispatch
def serialize(object_: Any) -> str:
raise TypeError('Serialization for objects '
'of type "{type}" is not supported.'
.format(type=type(object_)))
@serialize.register(int)
def serialize_int(object_: int) -> str:
return str(object_)
今、条件付きで装飾したいserialize_int
場合
log_int_overload = True # some condition here
if log_int_overload:
from functools import wraps
def log(function):
@wraps(function)
def wrapped(*args, **kwargs):
result = function(*args, **kwargs)
print('For {args}, {kwargs} function returned: {result}.'
.format(args=args,
kwargs=kwargs,
result=result))
return result
return wrapped
serialize_int = log(serialize_int)
それから電話する
>>> serialize(1)
'1'
ご覧のとおり、「古い」装飾のないバージョンを呼び出します。これは、「古い」オーバーロードを 1 つしか登録serialize
していないために発生し、それが新しい関数オブジェクトであるため、装飾について何も知らないためです。
問題
「ディスパッチャー」関数が変更を取得するようにオーバーロードを変更する方法は?
装飾後に再度登録できるのは理解してserialize_int
いますが、コードの重複の問題のようですが、他に方法はありますか?
または、より一般的には、関数オブジェクトをその場で変更することはできますか? 装飾__call__
属性は役に立ちません。