У меня есть декоратор, который принимает функцию и возвращает ту же функцию с некоторыми добавленными атрибутами:
import functools
from typing import *
def decorator(func: Callable) -> Callable:
func.attr1 = "spam"
func.attr2 = "eggs"
return func
Как указать возвращаемое значение decorator
? Я хочу, чтобы подсказка типа передала две части информации:
- возвращаемое значение -
Callable
- возвращаемое значение имеет атрибуты
attr1
иattr2
Если я напишу протокол,
class CallableWithAttrs(Protocol):
attr1: str
attr2: str
то я теряю Callable
. И, видимо, я не могу заставить протокол наследоваться от Callable
;
class CallableWithAttrs(Callable, Protocol):
attr1: str
attr2: str
mypy
говорит:
error: Invalid base class "Callable"
С другой стороны, если я просто использую Callable
, я теряю информацию о добавленных атрибутах.
Это, возможно, еще сложнее при введении переменных типа, т.е. когда декоратор должен возвращать тот же тип вызываемого объекта, что и данная функция func
, как указал MisterMiyagi в комментариях.
import functools
from typing import *
C = TypeVar('C', bound=Callable)
def decorator(func: C) -> C:
func.attr1 = "spam"
func.attr2 = "eggs"
return func
Что мне теперь делать? Я не могу наследовать от переменной типа:
class CallableWithAttrs(C, Protocol):
attr1: str
attr2: str
error: Invalid base class "C"
Intersection[CallableWithAttrs, Callable]
(которого не существует). - person Anakhand   schedule 30.06.2020decorator
, какое значение имеет то, чтоfunc
являетсяCallable
? Он никогда не называет это так, после утиного ввода я не вижу причин для искусственного ограничения его области действия толькоCallable
объектами (?) - person PiCTo   schedule 30.06.2020Callable
s. (Приведенный здесь пример является лишь минимальным примером.) - person Anakhand   schedule 30.06.2020Callable
с атрибутами илиfunc: Callable
? То есть, вам нужно сохранить подпись? - person MisterMiyagi   schedule 30.06.2020