On Oct 6, 7:01 pm, "Aaron \"Castironpi\" Brady" <[EMAIL PROTECTED]> wrote: > On Oct 6, 4:30 am, Fuzzyman <[EMAIL PROTECTED]> wrote: > > > > > On Oct 6, 1:13 am, MRAB <[EMAIL PROTECTED]> wrote: > > > > Fuzzyman wrote: > > > > Hello all, > > > > > I may well be being dumb (it has happened before), but I'm struggling > > > > to fix some code breakage with Python 2.6. > > > > > I have some code that looks for the '__lt__' method on a class: > > > > > if hasattr(clr, '__lt__'): > > > > > However - in Python 2.6 object has grown a default implementation of > > > > '__lt__', so this test always returns True. > > > > > >>> class X(object): pass > > > > ... > > > > >>> X.__lt__ > > > > <method-wrapper '__lt__' of type object at 0xa15cf0> > > > > >>> X.__lt__ == object.__lt__ > > > > False > > > > > So how do I tell if the X.__lt__ is inherited from object? I can look > > > > in the '__dict__' of the class - but that doesn't tell me if X > > > > inherits '__lt__' from a base class other than object. (Looking inside > > > > the method wrapper repr with a regex is not an acceptable answer...) > > > > > Some things I have tried: > > > > > >>> X.__lt__.__self__ > > > > <class '__main__.X'> > > > > >>> dir(X.__lt__) > > > > ['__call__', '__class__', '__cmp__', '__delattr__', '__doc__', > > > > '__format__', '__getattribute__', '__hash__', '__init__', '__name__', > > > > '__new__', '__objclass__', '__reduce__', '__reduce_ex__', '__repr__', > > > > '__self__', '__setattr__', '__sizeof__', '__str__', > > > > '__subclasshook__'] > > > > >>> X.__lt__.__func__ > > > > Traceback (most recent call last): > > > > File "<stdin>", line 1, in <module> > > > > AttributeError: 'method-wrapper' object has no attribute '__func__' > > > > > Hmmm... I can get this working with Python 2.6 with: > > > > > if '__lt__' in dir(cls): > > > > > The default implementation of '__lt__' doesn't appear in the dir of > > > > classes. However this fails with Python 3 where the default > > > > implementation *does* appear in the output of 'dir'. Any suggestions? > > > > Methods are objects. How do you know if two references refer to the > > > same object? You use "is": > > > > X.__lt__ is object.__lt__ > > > Didn't you see that even an equality test fails - so they are not the > > same (that being the problem)... > > > They are unbound method objects - in Python 3 the unbound method has > > gone away, so the problem is with Python 2.6. > > > Michael > > --http://www.ironpythoninaction.com/ > > Not tested extensively. > > class NoLTException( Exception ): pass > > class NoLT( object ): > def __lt__( self, other ): > raise NoLTException() > > class A( NoLT ): > pass > > class B( A ): > def __lt__( self, other ): > return self > > def test_lt( obj ): > try: > obj.__lt__( None ) > except NoLTException: > return False > except: > pass > return True > > > > >>> a= A() > >>> b= B() > >>> test_lt( a ) > False > >>> test_lt( b ) > True > > This method won't work for arbitrary classes, only ones that you > control, that inherit from 'NoLT'. The 'test_lt' function works by > trying to call '__lt__' on its argument. The parameter to it doesn't > matter because of what happens next. If '__lt__' raises a > NoLTException, you know it was inherited from NoLT. Otherwise, even > if another exception occurs, the object you know has '__lt__'. > > It's a very object oriented solution. Essentially you're inheriting > all the classes that you want to fail, from a class that does.
But not a very good solution to the problem... The specific problem is to determine if an arbitrary class implements a specified comparison method. The general problem (that gives rise to the specific problem) is to write a class decorator that can implement all comparison methods from a class that implements only one. See: http://code.activestate.com/recipes/576529/ Michael -- http://www.ironpythoninaction.com/ -- http://mail.python.org/mailman/listinfo/python-list