2

I want instances of my custom class to be able to compare themselves to one another for similarity. This is different than the __cmp__ method, which is used for determining the sorting order of objects.

Is there a magic method that makes sense for this? Is there any standard syntax for doing this?

How I imagine this could look:

>>> 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

Where <???> is the magic method name and <?> is the operator.

4

6 回答 6

4

Take a look at the numeric types emulation in the datamodel and pick an operator hook that suits you.

I don't think there is currently an operator that is an exact match though, so you'll end up surprising some poor hapless future code maintainer (could even be you) that you overloaded a standard operator.

For a Levenshtein Distance I'd just use a regular method instead. I'd find a one.similarity(other) method a lot clearer when reading the code.

于 2013-01-28T21:07:12.653 回答
3

well, you could override __eq__ to mean both boolean logical equality and 'fuzzy' simlirity, by returning a sufficiently weird result from __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

the default behavior of the comparator should be that it is Truthy only if the compared values are exactly equal, so that normal equality is unaffected

于 2013-01-28T21:28:17.230 回答
2

No, there is not. You can make a class method, but I don't think there is any intuitive operator to overload that would do what you're looking for. And, to avoid confusion, I would avoid overloading unless it is obviously intuitive.

I would simply call is CustomClass.similarity(y)

于 2013-01-28T21:09:00.937 回答
1

I don't think there is a magic method (and corresponding operator) that would make sense for this in any context.

However, if, with a bit of fantasy, your instances can be seen as vectors, then checking for similarity could be analogous to calculating the scalar product. It would make sense then to use __mul__ and multiplication sign for this (unless you have already defined product for CustomClass instances).

于 2013-01-28T21:05:53.980 回答
0

No magic function/operator for that.

When I think of "similarity" for ints and floats, I think of the difference being lower than a certain threshold. Perhaps that's something you might use?

E.g. being able to calculate the "difference" between your objects might be suitable in the sub method.

于 2013-01-28T21:25:02.613 回答
0

In the example you've cited, I would use difflib. This conducts spell-check like comparisons between strings. But in general, if you really are comparing objects rather than strings, then I agree with the others; you should probably create something context-specific.

于 2013-01-28T21:29:06.633 回答