Предисловие
Я использую однократную диспетчеризацию с 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__
не поможет .