7

タイトルは 3 つの質問と解釈できますが、実際の問題は簡単に説明できます。Linux システムでは、python 2.7.3 がインストールされており、python 3 の非互換性について警告されたいと思っています。したがって、コード スニペット ( tester.py) は次のようになります。

#!/usr/bin/python -3

class MyClass(object):    
    def __eq__(self, other):
        return False

このコード スニペットを実行すると (プロジェクトで使用している実際のコードではなく、問題を表示するだけだと考えられます)。

./tester.py

次の非推奨警告が表示されます。

./tester.py:3: DeprecationWarning: Overriding __eq__ blocks inheritance of __hash__ in 3.x
  class MyClass(object):

私の質問: このコード スニペットを変更して警告をなくす、つまりバージョン 3 と互換性を持たせるにはどうすればよいですか? 警告などを抑制するだけでなく、等価演算子を正しい方法で実装したいと考えています。

4

2 に答える 2

7

Python 3.4のドキュメントページから:

クラスが__eq__()メソッドを定義しない場合は、__hash__()操作も定義しないでください。定義されているが定義されて__eq__()いない__hash__()場合、そのインスタンスはハッシュ可能なコレクションのアイテムとして使用できません。クラスが可変オブジェクトを定義し、__eq__()メソッドを実装する__hash__()場合、ハッシュ可能コレクションの実装ではキーのハッシュ値が不変である必要があるため、実装しないでください(オブジェクトのハッシュ値が変更されると、間違ったハッシュバケットに配置されます)。

基本的に、関数を定義する必要があり__hash()__ます。

問題は、ユーザー定義クラスの場合、__eq()__および__hash()__関数が自動的に定義されることです。

x.__hash__()それとx == yの両方を意味するような適切な値を返します。x is yhash(x) == hash(y)

、だけを定義すると、__eq()____hash()__を返すように設定されNoneます。だからあなたは壁にぶつかるでしょう。

の実装に煩わされることを望まず__hash()__、オブジェクトが決してハッシュされないことが確実である場合のより簡単な方法__hash__ = Noneは、警告を処理するものを明示的に宣言するだけです。

于 2013-03-18T07:09:41.740 に答える
2

アレックス: python の -3 オプションは、潜在的な問題について警告しています。MyClass のインスタンスをセットで使用していないこと、またはマッピングのキーとして使用していないことを認識しないため、依存していた可能性のあるものが機能しないことを警告します。MyClass をそのように使用していない場合は、警告を無視してください。潜在的な問題を見つけるのに役立つツールです。最終的には、どの警告が実際に重要であるかを判断するための実際の知性を備えた人物であることが期待されます。

警告を抑制することを本当に気にしている場合、または実際に、クラスが可変であり、それがセットで使用されていないこと、またはマッピングのキーとして使用されていないことを確認したい場合-単純な割り当て__hash__ = None(Sudiptaが指摘したように)クラス本体がそれを行います。None は呼び出し可能ではないため、これによりインスタンスがハッシュ不可になります。

    class MyClass (object):
        def __eq__(self, other): return self is other
        __hash__ = None
于 2014-12-14T20:55:12.350 に答える