Код: Выделить всё
from typing import Callable, TypeVar, Generic
T = TypeVar("T")
U = TypeVar("U")
class From(Generic[T]):
def __init__(self, val: T):
self.val = val
@classmethod
def unit(cls, val):
return cls(val)
def bind(self, func: Callable[[T], U]):
return self.unit(func(self.val))
Код: Выделить всё
def to_string(i: int) -> str:
return str(i)
From(1).bind(to_string) # here, self.val = "1"
Эту проблему можно решить, вернув параметризованный экземпляр From в методе unit вот так:
Код: Выделить всё
class From(Generic[T]):
...
@classmethod
def unit(cls, val: U) -> "From[U]":
return From[U](val)
Однако проблема возникает, когда я позволяю другому классу наследовать от From. Я теряю общность:
Код: Выделить всё
class Just(From[T]):
pass
Just(1).bind(to_string) # equals From("1"), instead of Just("1")
Я знаю, что вы можете использовать cls.__orig_bases__ для поиска (Generic[~T])< /code>, если вы распечатаете его внутри unit.
Я подумал, может быть, вы можете сделать что-то вроде setattr(cls, "__orig_bases__", (Generic))
Но это кажется бессмысленным и на случай, если не будет обнаружено проверкой типов.
В идеале должен быть какой-то метод для self, который позволит вам для доступа к непараметризованному базовому классу, чтобы вы могли self.() .
Сейчас мое решение — добавить # type: ignore в unit, например итак:
Код: Выделить всё
@classmethod
def unit(cls, val: U) -> "From[U]":
"""Return a new instance of the same encapsulating class, wrapping `val`"""
return cls(val) # type: ignore
Подробнее здесь: https://stackoverflow.com/questions/792 ... od-in-pyth