Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OOP way to implement class for comparison in Python

Using Python, I am trying to implement a set of types including a "don't care" type, for fuzzy matching. I have implemented it like so:

class Matchable(object):        
    def __init__(self, match_type = 'DEFAULT'):
        self.match_type = match_type

    def __eq__(self, other):
        return (self.match_type == 'DONTCARE' or other.match_type == 'DONTCARE' \
or self.match_type == other.match_type)

Coming from an OO background, this solution seems inelegant; using the Matchable class results in ugly code. I'd prefer to eliminate match_type, and instead make each type its own class inherited from a superclass, then use type checking to do the comparisons. However type checking appears to be generally frowned upon:

http://www.canonical.org/~kragen/isinstance/

Is there are better (more pythonic) way to implement this functionality?

Note: I'm aware of the large number of questions and answers about Python "enums", and it may be that one of those answers is appropriate. The requirement for the overridden __ eq __ function complicates matters, and I haven't seen a way to use the proposed enum implementations for this case.

The best OO way I can come up with of doing this is:

class Match(object):
    def __eq__(self, other):
        return isinstance(self, DontCare) or isinstance(other, DontCare) or type(self) == type(other)

class DontCare(Match):
    pass

class A(Match):
    pass

class B(Match):
    pass

d = DontCare()
a = A()
b = B()


print d == a
True
print a == d
True
print d == b
True
print a == b
False
print d == 1
True
print a == 1
False
like image 654
Stefan Avatar asked May 04 '26 13:05

Stefan


1 Answers

The article you linked says that isinstance isn't always evil, and I think in your case it is appropriate. The main complaint in the article is that using isinstance to check whether an object supports a particular interface reduces opportunities to use implied interfaces, and it's a fair point. In your case, however, you would essentially be using a Dontcare class to provide an annotation for how an object should be treated in comparisons, and isinstance would be checking such an annotation, which should be perfectly. fine.

like image 184
Nikita Borisov Avatar answered May 07 '26 10:05

Nikita Borisov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!