あなたができない 1つ以上のクラスを扱っているなら内部から変更、これを行うには、diff固有のライブラリに依存しない一般的で簡単な方法があります。
非常に複雑なオブジェクトに対して安全で最も簡単な方法
pickle.dumps(a) == pickle.dumps(b)
picklePythonオブジェクト用の非常に一般的なシリアライゼーションライブラリであり、実際にはほとんどすべてをシリアライズできます。上記のスニペットではstr、シリアル化されたfromとfromのものを比較aしていますb。次のメソッドとは異なり、これにはカスタムクラスの型チェックの利点もあります。
最大の手間:特定の順序付けと[de / en]コーディングメソッドpickleにより、等しいオブジェクトに対して同じ結果が得られないことがあります。特に、頻繁に見られるような複雑なオブジェクト(ネストされたカスタムクラスインスタンスのリストなど)を扱う場合は特にそうです。一部のサードパーティライブラリで。そのような場合は、別の方法をお勧めします。
万物に安全な方法
シリアライズ可能なオブジェクトを提供する再帰的なリフレクションを記述して、結果を比較することができます
from collections.abc import Iterable
BASE_TYPES = [str, int, float, bool, type(None)]
def base_typed(obj):
    """Recursive reflection method to convert any object property into a comparable form.
    """
    T = type(obj)
    from_numpy = T.__module__ == 'numpy'
    if T in BASE_TYPES or callable(obj) or (from_numpy and not isinstance(T, Iterable)):
        return obj
    if isinstance(obj, Iterable):
        base_items = [base_typed(item) for item in obj]
        return base_items if from_numpy else T(base_items)
    d = obj if T is dict else obj.__dict__
    return {k: base_typed(v) for k, v in d.items()}
def deep_equals(*args):
    return all(base_typed(args[0]) == base_typed(other) for other in args[1:])
オブジェクトが何であるかは問題ではありませんが、深い平等が機能することが保証されています
>>> from sklearn.ensemble import RandomForestClassifier
>>>
>>> a = RandomForestClassifier(max_depth=2, random_state=42)
>>> b = RandomForestClassifier(max_depth=2, random_state=42)
>>> 
>>> deep_equals(a, b)
True
比較対象の数も重要ではありません
>>> c = RandomForestClassifier(max_depth=2, random_state=1000)
>>> deep_equals(a, b, c)
False
これの私のユースケースは、BDDテスト内ですでにトレーニングされた機械学習モデルの多様なセット間の深い同等性をチェックすることでした。モデルは、サードパーティのライブラリのさまざまなセットに属していました。確かに、__eq__ここで提案されている他の回答のように実装することは、私にとって選択肢ではありませんでした。
すべての拠点をカバー
比較されている1つ以上のカスタムクラスに実装がない__dict__シナリオが考えられます。これは決して一般的ではありませんが、sklearnのランダムフォレスト分類器内のサブタイプの場合です<type 'sklearn.tree._tree.Tree'>。ケースバイケースでこれらの状況を扱います。たとえば、具体的には、問題のタイプのコンテンツを、インスタンスに関する代表的な情報を提供するメソッド(この場合は__getstate__メソッド)のコンテンツに置き換えることにしました。そのため、最後から2番目の行base_typedは
d = obj if T is dict else obj.__dict__ if '__dict__' in dir(obj) else obj.__getstate__()
編集:組織のために、私は最後の2行に置き換えbase_typedとしreturn dict_from(obj)、そしてそれがよりあいまいなLIBSに適応するために、本当に一般的な反射を(私は、あなたにDoc2Vecを探しています)実装しました
def isproperty(prop, obj):
    return not callable(getattr(obj, prop)) and not prop.startswith('_')
def dict_from(obj):
    """Converts dict-like objects into dicts
    """
    if isinstance(obj, dict):
        # Dict and subtypes are directly converted
        d = dict(obj)
    elif '__dict__' in dir(obj):
        d = obj.__dict__
    elif str(type(obj)) == 'sklearn.tree._tree.Tree':
        # Replaces sklearn trees with their state metadata
        d = obj.__getstate__()
    else:
        # Extract non-callable, non-private attributes with reflection
        kv = [(p, getattr(obj, p)) for p in dir(obj) if isproperty(p, obj)]
        d = {k: v for k, v in kv}
    return {k: base_typed(v) for k, v in d.items()}
上記のどのメソッドも、次のように、Trueキーと値のペアは同じであるがキーと値の順序が異なる、異なるオブジェクトに対して生成されないことに注意してください。
>>> a = {'foo':[], 'bar':{}}
>>> b = {'bar':{}, 'foo':[]}
>>> pickle.dumps(a) == pickle.dumps(b)
False
しかし、もしそうしたいのであれば、sortedとにかく前もってPythonの組み込みメソッドを使うことができます。
               
              
return NotImplementedなく、を使用することに興味がありましたNotImplementedError。ここではカバーされているトピックの:stackoverflow.com/questions/878943/...