根据Python对象的属性生成唯一标识符

10

有没有一种方法可以在Python中为对象生成类似哈希的ID,该ID仅基于对象的属性值?例如,

class test:
    def __init__(self, name):
        self.name = name

obj1 = test('a')
obj2 = test('a')

hash1 = magicHash(obj1)
hash2 = magicHash(obj2)

我想要的是hash1等于hash2。在Python中是否有这样的东西?我知道我可以测试obj1.name == obj2.name,但我正在寻找一些通用的东西,可以在任何对象上使用。

4个回答

7
你是指像这样吗?使用特殊的方法__hash__
class test:
     def __init__(self, name):
         self.name = name
     def __hash__(self):
         return hash(self.name)

>>> hash(test(10)) == hash(test(20))
False
>>> hash(test(10)) == hash(test(10))
True

@Bastien,你说得对。但这真的取决于应用程序。对于许多情况,哈希可能已经足够了。 - Nadia Alramli
1
不建议在 hash(self) 中返回除 int(http://docs.python.org/reference/datamodel.html#object.__hash__)之外的任何内容,因为这会使对象表面上看起来不正确地可哈希化(如在字典中使用)。 - SingleNegationElimination
如果你有多个属性,元组也可以,例如: hash((self.first_name, self.last_name)) - Matt Good

3

获取唯一比较:

为了保证唯一性,您可以对数据进行序列化,然后比较序列化值,以确保完全匹配。

例如:

import pickle

class C:
  i = 1
  j = 2

c1 = C()
c2 = C()
c3 = C()
c1.i = 99

unique_hash1 = pickle.dumps(c1) 
unique_hash2 = pickle.dumps(c2) 
unique_hash3 = pickle.dumps(c3) 

unique_hash1 == unique_hash2 #False
unique_hash2 == unique_hash3 #True

如果您不需要每个对象拥有唯一值,但大部分都是唯一的:

请注意,相同的值始终会缩减为相同的哈希值,但两个不同的值可能会缩减为相同的哈希值。

您不能使用类似内置的hash()函数(除非您覆盖__hash__)。

hash(c1) == hash(c2) #False
hash(c2) == hash(c3) #False <--- Wrong

或者像使用pickle序列化数据,然后使用zlib.crc32进行处理。
import zlib
crc1 = zlib.crc32(pickle.dumps(c1))
crc2 = zlib.crc32(pickle.dumps(c2))
crc3 = zlib.crc32(pickle.dumps(c3))
crc1 == crc2 #False
crc2 == crc3 #True

对于唯一比较,如果您的对象非常大,您还可以使用zlib.compress使表示更小。 - Brian R. Bondy
不,pickle 不适合用于哈希。正如 Robert Brewer 所描述的那样,结果可能会有所不同:http://www.aminus.org/blogs/index.php/2007/11/03/pickle_dumps_not_suitable_for_hashing?blog=2 - Matt Good
不确定为什么,但是在CPython 2.5.1中,我无法重现他的行为。对我来说,它总是哈希到相同的结果。 - Brian R. Bondy
2
@Matt Good:如果你继续阅读博客文章的评论,你会发现这个问题是与cPickle而不是pickle有关。并且是由于引用计数引起的。 - Brian R. Bondy

2

我猜

def hash_attr(ins):
 return hash(tuple(ins.__dict__.items()))

哈希是根据实例的属性计算出来的。


2

请查看内置函数hash()和对象方法__hash__(),它们可能正是你需要的。你需要为自己的类实现__hash__()


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接