70

これが私のコードです:

class Hero:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __str__(self):
        return self.name + str(self.age)

    def __hash__(self):
        print(hash(str(self)))
        return hash(str(self))

heroes = set()

heroes.add(Hero('Zina Portnova', 16)) # gets hash -8926039986155829407
print(len(heroes)) # gets 1

heroes.add(Hero('Lara Miheenko', 17)) # gets hash -2822451113328084695
print(len(heroes)) # gets 2

heroes.add(Hero('Zina Portnova', 16)) # gets hash -8926039986155829407
print(len(heroes)) # gets 3! WHY?

なぜこうなった?
1番目と3番目のオブジェクトは同じコンテンツと同じハッシュを持っていますがlen()、3つの一意のオブジェクトについて教えてくれますか?

4

3 に答える 3

75

__eq__()また、と互換性のある方法で定義する必要があります__hash__()–そうでない場合、同等性はオブジェクトIDに基づきます。

Python 2では、との整合性を保つように定義__ne__することもお勧めします。Python 3では、デフォルトの実装がに委任されます。!===__ne____eq__

于 2012-06-12T09:55:13.313 に答える
26

これがコード全体です:

class Hero:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __str__(self):
        return self.name + str(self.age)

    def __hash__(self):
        print(hash(str(self)))
        return hash(str(self))

    def __eq__(self,other):
        return self.name == other.name and self.age== other.age



heroes = set()
heroes.add(Hero('Zina Portnova', 16)) # gets hash -8926039986155829407
print(len(heroes)) # gets 1

heroes.add(Hero('Lara Miheenko', 17)) # gets hash -2822451113328084695
print(len(heroes)) # gets 2

heroes.add(Hero('Zina Portnova', 16)) # gets hash -8926039986155829407
print(len(heroes)) # gets 2 

この関数はを認識し、__eq__そのためlenは2です。

于 2016-07-08T04:51:38.810 に答える
9

Pythonのドキュメントが役立つ場合があります。

クラスが__cmp__()または__eq__()メソッドを定義しない場合は、__hash__()操作も定義しないでください。

于 2015-07-09T15:45:50.177 に答える