Angenommen, ich habe zwei Klassen Base
und Child
mit einer Factory-Methode in Base
. Die Factory-Methode ruft eine andere Klassenmethode auf, die durch die untergeordneten Klassen Base
überschrieben werden kann.Python 3 Typhinweis für eine Factory-Methode auf einer Basisklasse, die eine Kindklasseninstanz zurückgibt
class Base(object):
@classmethod
def create(cls, *args: Tuple) -> 'Base':
value = cls._prepare(*args)
return cls(value)
@classmethod
def _prepare(cls, *args: Tuple) -> Any:
return args[0] if args else None
def __init__(self, value: Any) -> None:
self.value = value
class Child(Base):
@classmethod
def _prepare(cls, *args: Tuple) -> Any:
return args[1] if len(args) > 1 else None
def method_not_present_on_base(self) -> None:
pass
Gibt es eine Möglichkeit Base.create
so zu beschriften, dass ein statisches Typprüfer ableiten könnte, dass Base.create()
eine Instanz von Base
zurückgegeben und Child.create()
zurück eine Instanz Child
, so dass das folgende Beispiel statische Analyse passieren würde?
base = Base.create(1)
child = Child.create(2, 3)
child.method_not_present_on_base()
Im obigen Beispiel würde ein statisches Typprüfer zu Recht beklagt, dass die method_not_present_on_base
ist, na ja, nicht auf der Base
Klasse.
Ich dachte über Base
in eine generische Klasse drehen und die untergeordneten Klassen geben sich als Typ Argumente aufweisen, das heißt die CRTP zu Python zu bringen.
T = TypeVar('T')
class Base(Generic[T]):
@classmethod
def create(cls, *args: Tuple) -> T: ...
class Child(Base['Child']): ...
Aber das fühlt sich eher unpythonic mit CRTP von C++ kommen und alle ...
Ehrfürchtig, danke! Unglücklicherweise behandelt PyCharm nun private Methoden auf "cls" als Zugriff auf ein privates Mitglied auf einem anderen Objekt, aber mypy behandelt dies wie erwartet. – PoByBolek
Das ist wirklich cool! Vielen Dank für Ihre Antwort. – bjd2385