Python重写字符串__hash__方法

6

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

还是创建一个包含字符串并覆盖__hash____eq__的包装类是唯一的方法?


我会使用包装类。它既清晰明了,又不会通过假装成字符串而导致完全不同的哈希值而引起混淆。 - millimoose
1
在使用哈希作为键的容器中混合使用strcustom_str可能会很有趣 :) - Jon Clements
虽然你可以这样做,但我认为另一种方法可能会更好。例如,定义一个函数来分类字符串,并将其用作排序键。 - Keith
1
那么,如果你把它们作为字典的键,你想让 ih 替换 hi 吗? - Keith
@Keith 不对,我是将排序后的顺序作为键,实际字符串作为值插入列表中。 - darksky
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)

1
假设我创建了一个返回哈希值的自由函数。我该如何将该键插入到返回的哈希位置?dict = {},dict [5] = value会将value插入到位置5还是键'5'? - darksky
将值放入字典中确实意味着更改相等语义,这是正确的方法。您可以选择将包装器结构化为一个信封,其中具有原始字符串作为实例属性。 - SingleNegationElimination

0

你的假设是正确的,你不能在Python中覆盖基类。虽然可以重写str()会做什么,但对于字符串字面值不起作用。

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

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

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


拒绝使用UserString,那是古老的历史了。只需从str继承即可,例如class mystr(str): ... - Jon Clements
它说如果我不需要支持2.2版本之前的向后兼容性,我可以直接从内置的str子类化。那该怎么做呢?只需要这样吗:class wrapper_class(str):?仅覆盖__hash____eq__就足够了吗? - darksky
@JonClements,你刚刚回答了我评论的第一部分 :) 那么方法覆盖呢?__hash____eq__是否足够? - darksky
@JonClements 如果您将其作为单独的答案放置,我会将其标记为正确。 - darksky
@darksky 我正在思考这个问题,想知道是否有其他方法。你能否在你的问题中解释一下你的确切用例? - Jon Clements
显示剩余2条评论

0

你可以继承自str,但由于它们是不可变的,所以你必须以稍微不同的方式对它们进行子类化。最有可能的是,你想要从现有字符串创建新的字符串,因此你还必须重写__new__方法。你可能还需要添加额外的特殊方法来打败Python所做的优化。

这里有一个内置str的子类化示例,mapstr对象允许在表单中轻松替换占位符。


你能解释一下你所说的“很可能你想从现有字符串创建新的字符串”是什么意思吗?我只想创建一个可以传递到__init__的字符串,那我为什么需要子类化__new__呢?如果我不这样做会发生什么? - darksky
那么你打算如何使用它? - Keith
将具有相同字符的字符串哈希到一个键中。值是所有字符串的列表。键是它们的排序版本。 - darksky

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