6

我正在尝试为字符串创建自定义散列函数。我想通过权重的字符频率对字符串进行哈希处理。这样,hi就会ih产生相同的哈希值。我可以覆盖__hash__吗?

或者正在创建一个包含字符串和覆盖的包装类,__hash__并且__eq__是唯一的方法?

4

3 回答 3

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)
于 2012-11-21T23:34:32.713 回答
0

您的假设是正确的,您不能覆盖 Python 中的基类。当然,虽然可以覆盖str()将要执行的操作,但它不适用于字符串文字。

如果您正在为 pre-python 2.2 编写代码,UserString如果您想创建自己的,请查看该类:http: //docs.python.org/2/library/userdict.html#module-UserString

否则,您可以简单地继承strunicode

__hash__在您的情况下,如果您想将其用作 dict 键,只需覆盖该方法就足够了。但是,如果您正在查看比较,则必须覆盖__eq____cmp__

于 2012-11-21T22:43:11.830 回答
0

您可以从 继承str,但由于它们是不可变的,因此您必须以稍微不同的方式对它们进行子类化。您很可能希望从现有字符串创建新字符串,因此您还必须覆盖该__new__方法。您可能还必须使用额外的特殊方法来破坏 Python 所做的优化。

这是一个子类化 built-in 的示例,它允许在表单中轻松替换占位符strmapstr对象。

于 2012-11-21T23:20:04.253 回答