我正在尝试为字符串创建自定义散列函数。我想通过权重的字符频率对字符串进行哈希处理。这样,hi
就会ih
产生相同的哈希值。我可以覆盖__hash__
吗?
或者正在创建一个包含字符串和覆盖的包装类,__hash__
并且__eq__
是唯一的方法?
您需要具有不同相等语义的派生类型。通常采用的方法是定义相等性如何工作,然后从那里派生的结构构建散列方法,因为散列必须与相等性一致。那可能是:
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)
您的假设是正确的,您不能覆盖 Python 中的基类。当然,虽然可以覆盖str()
将要执行的操作,但它不适用于字符串文字。
如果您正在为 pre-python 2.2 编写代码,UserString
如果您想创建自己的,请查看该类:http: //docs.python.org/2/library/userdict.html#module-UserString
否则,您可以简单地继承str
或unicode
__hash__
在您的情况下,如果您想将其用作 dict 键,只需覆盖该方法就足够了。但是,如果您正在查看比较,则必须覆盖__eq__
或__cmp__
您可以从 继承str
,但由于它们是不可变的,因此您必须以稍微不同的方式对它们进行子类化。您很可能希望从现有字符串创建新字符串,因此您还必须覆盖该__new__
方法。您可能还必须使用额外的特殊方法来破坏 Python 所做的优化。
这是一个子类化 built-in 的示例,它允许在表单中轻松替换占位符str
的mapstr对象。