0

序文

のようなデコレータで単一のディスパッチを使用しています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__属性は役に立ちません

4

0 に答える 0