Обновление однократной перегрузки после оформления - PullRequest
0 голосов
/ 18 октября 2018

Предисловие

Я использую однократную диспетчеризацию с 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'

, как мы видим, вызывает "старую", неокрашенную версию.Это происходит потому, что мы зарегистрировали только «старую» одну перегрузку и serialize ничего не знаем о оформленном, поскольку это новый функциональный объект.

Проблема

Как изменить перегрузки так, чтобыФункция «диспетчер» будет захватывать изменения?

Я понимаю, что мы можем зарегистрировать serialize_int снова после декорирования, но похоже на проблему с повторением кода, есть ли другой способ?

Илив более общем смысле: можем ли мы как-то изменить функциональный объект на месте?Украшение атрибута __call__ не поможет .

...