12

私は Python 3.5.1 と、新しくリリースされたMyPy v0.4.1 静的型アナライザーを使用しています。

エラーを再現するために必要なこの可能な限り単純な python クラスに縮小した、より複雑なコードがいくつかあります。

class MyObject(object):
    def __init__(self, value: int=5) -> None:
        self.value = value

    def __eq__(self, other: MyObject) -> bool:
        return self.value == other.value

型チェッカーを実行mypy test.pyすると、次のエラーが発生します。

test.py: note: In class "MyObject":
test.py:5: error: Argument 1 of "__eq__" incompatible with supertype "object"

これらのドキュメントに基づく私の理論は__eq____ne__オブジェクトには既に定義された型があり、これらの型のサブクラスの再定義と衝突しているというものです。私の質問は、これらの型を定義__eq__して、選択した型で型チェックされていることを確認する方法です。

4

3 に答える 3

13

==あなたのタイプのオブジェクトだけでなく、任意の他のオブジェクトを取ることになっています。他のオブジェクトを認識しない場合は、次を返す必要がありますNotImplemented

class MyObject(object):
    def __init__(self, value: int=5) -> None:
        self.value = value

    def __eq__(self, other: object) -> bool:
        if not isinstance(other, MyObject):
            return NotImplemented
        return self.value == other.value

NotImplementedのインスタンスではありませんboolが、mypy には奇妙な特殊なケースがあるようです。return アノテーションを にする必要がありbool、その行について文句を言うことはありませんreturn NotImplemented

また、MyObject本体内の型ヒントを参照する必要がある場合は、 の'MyObject'代わりに文字列を使用する必要がありますMyObjectMyObjectまだ存在しません。

于 2016-06-01T00:10:33.187 に答える
3

ドキュメントの読み方は正しいです。メソッド ( __eq__) に、基本クラス ( ) に既にあるものと同じシグネチャを与えるobjectか、より寛容なシグネチャを与える必要があります。

その理由は、 yourMyObjectが のサブタイプであるためobject、 aが ... をMyObject期待する場所ならどこでも渡される可能性があるためobjectです。これは、そのコードがそれを他の と比較できることを意味しobject、型チェッカーが文句を言う正当な方法がないことを意味します。したがって、それを反映するには、__eq__any を期待するように記述する必要がありますobject

あなたができることは、メソッドの本体のすぐ前にあり、型をチェックして返す(または例外を発生させる)ことです:

if not isinstance(other, MyObject):
  return False

次に、それらのドキュメントが言うように、Mypy は十分に賢いので、そのチェックの後、それotherが aであることを認識し、MyObjectそれに応じて処理します。

于 2016-06-01T01:15:58.693 に答える