Gen*_*tal 32 python identity equality set operator-keyword
class A(object):
def __cmp__(self):
print '__cmp__'
return object.__cmp__(self)
def __eq__(self, rhs):
print '__eq__'
return True
a1 = A()
a2 = A()
print a1 in set([a1])
print a1 in set([a2])
Run Code Online (Sandbox Code Playgroud)
为什么第一行打印为True,但第二行打印为False?既不进入运营商eq?
我使用的是Python 2.6
Ray*_*ger 16
设置__contains__按以下顺序进行检查:
'Match' if hash(a) == hash(b) and (a is b or a==b) else 'No Match'
Run Code Online (Sandbox Code Playgroud)
相关的C源代码位于Objects/setobject.c :: set_lookkey()和Objects/object.c :: PyObject_RichCompareBool()中.
Dav*_*ver 15
你也需要定义__hash__.例如
class A(object):
def __hash__(self):
print '__hash__'
return 42
def __cmp__(self, other):
print '__cmp__'
return object.__cmp__(self, other)
def __eq__(self, rhs):
print '__eq__'
return True
a1 = A()
a2 = A()
print a1 in set([a1])
print a1 in set([a2])
Run Code Online (Sandbox Code Playgroud)
将按预期工作.
作为一般规则,任何时候你实现__cmp__你应该实现一个__hash__这样的,所有x,y如此x == y,x.__hash__() == y.__hash__().
集合和字典通过使用散列作为完全相等性检查的快速近似来获得其速度.如果要重新定义相等性,通常需要重新定义哈希算法以使其保持一致.
默认的哈希函数使用对象的标识,这对于完全相等的快速近似是相当无用的,但至少允许您使用任意类实例作为字典键并检索与其一起存储的值如果您准确传递与键相同的对象.但这意味着如果你重新定义相等并且不重新定义哈希函数,那么你的对象将进入字典/集合而不会抱怨不可用,但仍然不会按照你期望的方式工作.
有关更多详细信息,请参阅官方python文档__hash__.
| 归档时间: |
|
| 查看次数: |
7843 次 |
| 最近记录: |