Я хочу иметь возможность сделать это:
from typing import Type
from functools import singledispatch
class A:
pass
class B(A):
pass
@singledispatch
def foo(arg):
print('default')
@foo.register
def _(arg: Type[A]):
print(arg)
foo(A)
foo(B)
Тем не менее, я получаю Invalid annotation for 'arg'. typing.Type[__main__.arg] is not a class.
Я предполагаю, что singledispatch просто пока не поддерживает typing полностью. Есть ли какой-нибудь элегантный обходной путь?
УПД
Я не могу изменить A и B.






Вы можете дать A метакласс, и тогда все подклассы A будут экземплярами этого метакласса:
from functools import singledispatch
class AMeta(type): pass
class A(metaclass=AMeta): pass
class B(A): pass
@singledispatch
def foo(arg):
print('default')
@foo.register
def _(arg: AMeta):
print('A or B')
foo(A) # A or B
foo(B) # A or B
foo(A()) # default
class C: pass
foo(C) # default
Спасибо! Я думал об этом. Обновил мой вопрос, у меня нет прямого доступа к A и B. В этом случае, если я попытаюсь обернуть их, я думаю, может быть сложно добавить желаемый метакласс из-за mro. Должен ли я принять ответ?
@Tzoiker Нет, если это не решит вашу проблему. Просто для ясности: вы хотите, чтобы функция вел себя по-другому, если передал объект, представляющий A или один из его подклассов? singledispatch возможно, вы не сможете этого сделать, вы можете использовать if issubclass(arg, A): return func1(arg) else return func2(arg)
Я закончил тем, что сделал это. Было просто любопытно, можно ли это обработать по-другому.
Итак, вы хотите, чтобы
fooвело себя по-разному при передачеAилиBв качестве аргументов?