Base
とChild
の2つのクラスがファクトリメソッドBase
にあるとします。ファクトリメソッドは、Base
の子クラスによって上書きされるかもしれない別のクラスメソッドを呼び出します。子クラスのインスタンスを返すベースクラスのファクトリメソッドのヒント:
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
静的型チェッカーは、Base.create()
がBase
のインスタンスを返し、次の例では、静的解析を通過するようにChild.create()
は、Child
のインスタンスを返したことを推測することができるようにBase.create
に注釈を付ける方法はありますか?
base = Base.create(1)
child = Child.create(2, 3)
child.method_not_present_on_base()
は、上記の例では、静的な型チェックは当然method_not_present_on_base
をBase
クラスに存在しない、十分であることを訴えることになります。
私は、ジェネリッククラスにBase
を回すと、子クラスは、すなわちPythonのにCRTPをもたらし、型引数として自分自身を指定することについて考えました。
T = TypeVar('T')
class Base(Generic[T]):
@classmethod
def create(cls, *args: Tuple) -> T: ...
class Child(Base['Child']): ...
しかし、これはCRTPは、C++およびすべてから来るとむしろunpythonic感じ...
ありがとうございます!残念ながら、PyCharmは 'cls'のプライベートメソッドを別のオブジェクトのプライベートメンバにアクセスするように扱いますが、mypyはこれを期待通りに扱います。 – PoByBolek
これは本当にクールです!あなたの答えに感謝します。 – bjd2385