2017-12-19 17 views
2

私の問題は、物事を行うタイプAのクラスを持っていて、それらの関数をサブクラス(B)として使用すると、それらはクラスAのために型付きされ、クラスBオブジェクトを引数として受け取りません。 。簡略化され継承された型ヒントをPythonで持つ方法は?

私の問題:

from typing import TypeVar, Generic, Callable 

T = TypeVar('T') 


class Signal(Generic[T]): 
    def connect(self, connector: Callable[[T], None]) -> None: 
     pass 

    def emit(self, payload: T): 
     pass 


class A: 
    def __init__(self) -> None: 
     self.signal = Signal[A]() 

    def do(self) -> None: 
     self.signal.emit(self) 

def handle_b(b: "B") -> None: 
    print(b.something) 

class B(A): 
    def __init__(self) -> None: 
     super().__init__() 
     self.signal.connect(handle_b) 

    @property 
    def something(self) -> int: 
     return 42 

は、私は同様に完全な信号クラスを提供することができますが、それは単に問題からそらします。これにより、mypy - >エラーに1つのエラーが表示されます。 "Signal"の "connect"への引数1に、互換性のない型Callable [[B]、None]があります。予想される呼び出し可能な[[A]、[なし]シグナル処理は、それが明確に問題ないはずにもかかわらず、B型のオブジェクトが返されることを期待することはできませんサブクラスBに実装されているため

...

+0

さて、エラーは正しいです。あなたは 'self.signal = Signal [A]()'に 'self.signal'を' A'だけに制限しました。 –

+0

基本的に 'T = A'を設定します。 'B'はサブクラスかもしれませんが、' A.something'は存在しないので、その属性を使うことはできません。あなたは今すべてを「A」に結びつけました。 'B'を受け入れるメソッドは' B.something'を使うことが許されているので、基本クラス 'A'はその要件を満たすことができません。 –

答えて

0

タイプヒントのエラーは完全に正しいです。あなたはA__init__方法では、タイプとしてASignalインスタンスを作成:サブクラスに渡す

self.signal = Signal[A]() 

は大丈夫ですが、そのSignalインスタンスと対話するすべてのコードは今だけAインスタンスのために働くを持っています。一方、handle_b()Bのインスタンスを必要とし、その代わりに要求をAに引き下げることはできません。

ドロップ制約:

self.signal = Signal() 

又は正しいタイプと各サブクラスでインスタンスを作成します。

+0

A型のサブタイプを受け入れるようにヒントを伝える方法はありませんか? タイピング作業を無効にすることを意味しますが、なぜタイプヒントがあるのでしょうか... – user2799096

+0

申し訳ありませんが、しばらくキーボードから離していました。 'A 'の代わりに共変変数としてマークされた' TypeVar() 'を使用することはおそらく可能ですが、明日までテストすることはできません。 –

+0

私はすでにそれを試してみましたが、私はproblem.py:10を取得しました:エラー:共分散型の変数をパラメータとして使用できません :def emit(self、payload:T): まだ古いエラーがあります: Dはおそらく私のmypyバージョンをアップグレードする... – user2799096

関連する問題