在Python中,是否有一种很好的“魔术方法”来表示对象的相似性?

时间:2013-01-28 20:59:57

标签: python

我希望我的自定义类的实例能够将自己相互比较以获得相似性。这与__cmp__方法不同,后者用于确定对象的排序顺序。

有没有一种神奇的方法对此有意义?这样做有什么标准语法吗?

我的想象如下:

>>> x = CustomClass("abc")
>>> y = CustomClass("abd")
>>> z = CustomClass("xyz")
>>> x.__<???>__(y)
0.75
>>> x <?> y
0.75
>>> x.__<???>__(z)
0.0
>>> x <?> z
0.0

其中<???>是魔术方法名称,<?>是运算符。

6 个答案:

答案 0 :(得分:4)

查看numeric types emulation in the datamodel并选择适合您的操作员挂钩。

我不认为目前有一个完全匹配的运算符,所以你最终会让一些可怜的未来代码维护者(甚至可能是你)感到惊讶,因为你重载了标准运算符。

对于Levenshtein距离,我只使用常规方法。在阅读代码时,我会发现one.similarity(other)方法更加清晰。

答案 1 :(得分:3)

好吧,你可以覆盖__eq__来表示布尔逻辑相等和'模糊'同形,通过从__eq__返回一个足够奇怪的结果:

class FuzzyBool(object):
    def __init__(self, quality, tolerance=0):
        self.quality, self._tolerance = quality, tolerance
    def __nonzero__(self):
        return self.quality <= self._tolerance
    def tolerance(self, tolerance):
        return FuzzyBool(self.quality, tolerance) 
    def __repr__(self):
        return "sorta %s" % bool(self)

class ComparesFuzzy(object):
    def __init__(self, value):
        self.value = value
    def __eq__(self, other):
        return FuzzyBool(abs(self.value - other.value))
    def __hash__(self):
        return hash((ComparesFuzzy, self.value))
>>> a = ComparesFuzzy(1)
>>> b = ComparesFuzzy(2)
>>> a == b
sorta False
>>> (a == b).tolerance(3)
sorta True

比较器的默认行为应该是只有当比较值完全相等时才是Truthy,这样正常的相等性不受影响

答案 2 :(得分:2)

不,没有。你可以创建一个类方法,但我认为没有任何直观的操作符可以超载,可以满足您的需求。并且,为了避免混淆,我会避免超载,除非它显然是直观的。

我只需调用CustomClass.similarity(y)

答案 3 :(得分:1)

我不认为在任何情况下都有一个神奇的方法(和相应的运算符)对此有意义。

然而,如果有点幻想,你的实例可以看作是向量,那么检查相似性可能类似于计算标量积。那么为此使用__mul__和乘法符号是有意义的(除非您已经为CustomClass个实例定义了产品)。

答案 4 :(得分:0)

没有神奇的功能/操作员。

当我想到整数和浮点数的“相似性”时,我认为差异低于某个阈值。也许你可以使用它?

E.g。能够计算对象之间的“差异”可能适合 sub 方法。

答案 5 :(得分:0)

在你引用的例子中,我会使用difflib。这会进行拼写检查,就像字符串之间的比较一样。但总的来说,如果你真的在比较对象而不是字符串,那么我同意其他对象;你应该创建一些特定于上下文的东西。