我正在尝试为字符串创建自定义哈希函数。我想按重量按字符频率散列字符串。因此hi
和ih
将产生相同的哈希值。我可以覆盖__hash__
吗?
或者是创建一个包含字符串的包装类,并以唯一的方式覆盖__hash__
和__eq__
?
答案 0 :(得分:4)
您希望派生类型具有不同的相等语义。通常采用的方法是定义平等如何工作,然后从派生的结构中构建哈希方法,因为哈希必须与相等一致。那可能是:
import collections
class FrequencyString(str):
@property
def normalized(self):
try:
return self._normalized
except AttributeError:
self._normalized = normalized = ''.join(sorted(collections.Counter(self).elements()))
return normalized
def __eq__(self, other):
return self.normalized == other.normalized
def __hash__(self):
return hash(self.normalized)
答案 1 :(得分:0)
您的假设是正确的,您不能覆盖Python中的基本条款。当然,虽然可以覆盖str()
将执行的操作,但它不适用于字符串文字。
如果您要为pre-python 2.2编写代码,请查看UserString
类,如果您想创建自己的代码:http://docs.python.org/2/library/userdict.html#module-UserString
否则您只需继承str
或unicode
在您的情况下,如果您想将其用作dict键,只需覆盖__hash__
方法就足够了。但是,如果您正在查看比较,则必须覆盖__eq__
或__cmp__
答案 2 :(得分:0)
您可以从str
继承,但由于这些是不可变的,您必须以稍微不同的方式对它们进行子类化。您很可能希望从现有字符串创建新的字符串,因此您还必须覆盖__new__
方法。您可能还需要使用额外的特殊方法来破坏Python所做的优化。
这是一个子类化内置str
的示例,mapstr对象允许在表单中轻松替换占位符。