Вдохновленный Мухаммадом Алкарури ответил в What are good uses for Python3's "Function Annotations", я хочу это сделать multimethod
для методов, а не регулярных функций. Однако, когда я делаю этоМетод украшения (перегрузка методов класса)
registry = {}
class MultiMethod(object):
def __init__(self, name):
self.name = name
self.typemap = {}
def __call__(self, *args):
types = tuple(arg.__class__ for arg in args) # a generator expression!
function = self.typemap.get(types)
if function is None:
raise TypeError("no match")
return function(*args)
def register(self, types, function):
if types in self.typemap:
raise TypeError("duplicate registration")
self.typemap[types] = function
def multimethod(function):
name = function.__name__
mm = registry.get(name)
if mm is None:
mm = registry[name] = MultiMethod(name)
types = tuple(function.__annotations__.values())
mm.register(types, function)
return mm
class A:
@multimethod
def foo(self, a: int):
return "an int"
a = A()
print(a.foo(1))
Я получил это:
Traceback (most recent call last):
File "test.py", line 33, in <module>
print(a.foo(1))
File "test.py", line 12, in __call__
return function(*args)
TypeError: foo() takes exactly 2 arguments (1 given)
который, кажется, можно ожидать, как объяснено в Decorating a method, из-за self
аргумента.
Но я не знаю, как заставить его работать. Ну, когда я удаляю «я», он работает (почти) отлично, но я не хочу его удалять. Обратите внимание, что я делаю это для практики, я знаю, что есть некоторые библиотеки, обеспечивающие перегрузку метода.
Что я пробовал:
очень глупо, но хотел бы попробовать, - добавил параметр
self
вdef multimethod(function)
- та же ошибкаЯ думал о добавлении в
__init__
изclass MultiMethod
третьего параметра -obj
и сохраненself
как член, но я не могу сделать это черезmultimethod
, поскольку это функция.Я не хочу, чтобы добавить параметры для декоратора, поэтому эти опции (если вообще возможно) игнорируется
Я прочитал несколько подобных вопросов, но не нашли то, что я искал для. Я почти уверен, что это фиктивный вопрос, но у меня кончились идеи.
Haaa, спасибо, это действительно имеет смысл. +1 и принято. –