Disons que j'ai deux classes Base
et Child
avec une méthode usine dans Base
. La méthode factory appelle une autre méthode de classe qui peut être surchargée par les classes enfants de Base
.Indice de type Python 3 pour une méthode usine sur une classe de base renvoyant une instance de classe enfant
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
Est-il possible d'annoter Base.create
de sorte qu'un vérificateur de type statique pourrait en déduire que Base.create()
a renvoyé une instance de Base
et Child.create()
a renvoyé une instance de Child
, de sorte que l'exemple suivant passerait l'analyse statique?
base = Base.create(1)
child = Child.create(2, 3)
child.method_not_present_on_base()
Dans l'exemple ci-dessus un vérificateur de type statique se plaindraient à juste titre que le method_not_present_on_base
est, bien, pas présent sur la classe Base
.
Je pensais à tourner Base
dans une classe générique et ayant les classes d'enfants définissent elles-mêmes comme des arguments de type, à savoir amener le CRTP à Python.
T = TypeVar('T')
class Base(Generic[T]):
@classmethod
def create(cls, *args: Tuple) -> T: ...
class Child(Base['Child']): ...
Mais cela se sent plutôt unpythonic avec CRTP venant de C++ et tout ...
Génial, merci! Malheureusement, PyCharm traite maintenant les méthodes privées sur 'cls' comme accédant à un membre privé sur un autre objet, mais mypy le traite comme prévu. – PoByBolek
C'est vraiment cool! Merci beaucoup pour votre réponse. – bjd2385