472,364 Members | 2,124 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,364 software developers and data experts.

Python 2.6 / 3.0: Determining if a method is inherited

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?

Michael Foord
--
http://www.ironpythoninaction.com/
Oct 5 '08 #1
8 2495
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__
Oct 6 '08 #2
On Oct 5, 7:13*pm, MRAB <goo...@mrabarnett.plus.comwrote:
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.
Hmmm... I can get this working with Python 2.6 with:

Methods are objects. How do you know if two references refer to the
same object? You use "is":

X.__lt__ is object.__lt__
That doesn't work for me.
>>class A( object ):
.... pass
....
>>class B( A ):
.... def __lt__( self, other ):
.... return self
....
>>a= A()
b= B()
B.__lt__ is object.__lt__
False
>>A.__lt__ is object.__lt__
False
>>>
Further, it's been noted before that

A().meth is not A().meth
Oct 6 '08 #3
On Oct 6, 1:13 am, MRAB <goo...@mrabarnett.plus.comwrote:
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/
Oct 6 '08 #4
On Oct 6, 4:30*am, Fuzzyman <fuzzy...@gmail.comwrote:
On Oct 6, 1:13 am, MRAB <goo...@mrabarnett.plus.comwrote:
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.
Oct 6 '08 #5
On Oct 6, 7:01*pm, "Aaron \"Castironpi\" Brady" <castiro...@gmail.com>
wrote:
On Oct 6, 4:30*am, Fuzzyman <fuzzy...@gmail.comwrote:
On Oct 6, 1:13 am, MRAB <goo...@mrabarnett.plus.comwrote:
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/
Oct 6 '08 #6
On Oct 6, 1:17*pm, Fuzzyman <fuzzy...@gmail.comwrote:
On Oct 6, 7:01*pm, "Aaron \"Castironpi\" Brady" <castiro...@gmail.com>
wrote:
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/
Nope, I'm out of ideas, I'm afraid.
Oct 6 '08 #7
2008/10/5 Fuzzyman <fu******@gmail.com>:
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...)
I don't have Python 2.6 available, but if __lt__ on it works similarly
as __str__ on Python 2.5, you might be able to achieve this either
with inspect.ismethod or by checking methods' im_class attribute
directly:
>>class C(object):
.... pass
....
>>class D(object):
.... def __str__(self):
.... return ''
....
>>class E(D):
.... pass
....
>>import inspect
inspect.ismethod(C().__str__)
False
>>inspect.ismethod(D().__str__)
True
>>inspect.ismethod(E().__str__)
True
>>>
C().__str__.im_class
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'method-wrapper' object has no attribute 'im_class'
>>D().__str__.im_class
<class '__main__.D'>
>>E().__str__.im_class
<class '__main__.E'>
Cheers,
.peke
Oct 6 '08 #8
2008/10/7 Pekka Laukkanen <pe**@iki.fi>:
2008/10/5 Fuzzyman <fu******@gmail.com>:
>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...)

I don't have Python 2.6 available, but if __lt__ on it works similarly
as __str__ on Python 2.5, you might be able to achieve this either
with inspect.ismethod or by checking methods' im_class attribute
directly:
>>>class C(object):
... pass
...
>>>class D(object):
... def __str__(self):
... return ''
...
>>>class E(D):
... pass
...
>>>import inspect
inspect.ismethod(C().__str__)
False
>>>inspect.ismethod(D().__str__)
True
>>>inspect.ismethod(E().__str__)
True
>>>>
C().__str__.im_class
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'method-wrapper' object has no attribute 'im_class'
>>>D().__str__.im_class
<class '__main__.D'>
>>>E().__str__.im_class
<class '__main__.E'>
Ooops, didn't notice this was suggested already. One more attempt,
hopefully this is unique. =)
>>C().__str__.__objclass__
<type 'object'>
>>D().__str__.__objclass__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'function' object has no attribute '__objclass__'
>>'spam'.__str__.__objclass__
<type 'str'>

Someone who actually knows what __objclas__ does can probably comment
does this make any sense in your case.

Cheers,
.peke
Oct 6 '08 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

10
by: Andrew Dalke | last post by:
Is there an author index for the new version of the Python cookbook? As a contributor I got my comp version delivered today and my ego wanted some gratification. I couldn't find my entries. ...
86
by: Matthias Kaeppler | last post by:
Hi, sorry for my ignorance, but after reading the Python tutorial on python.org, I'm sort of, well surprised about the lack of OOP capabilities in python. Honestly, I don't even see the point at...
267
by: Xah Lee | last post by:
Python, Lambda, and Guido van Rossum Xah Lee, 2006-05-05 In this post, i'd like to deconstruct one of Guido's recent blog about lambda in Python. In Guido's blog written in 2006-02-10 at...
11
by: Fuzzyman | last post by:
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: ...
0
by: Fuzzyman | last post by:
Hello all, Sorry - my messages aren't showing up via google groups, so I'm kind of posting on faith... Anyway, I solved my problem (I think)... import sys if sys.version_info == 3:
2
by: Kemmylinns12 | last post by:
Blockchain technology has emerged as a transformative force in the business world, offering unprecedented opportunities for innovation and efficiency. While initially associated with cryptocurrencies...
0
by: Naresh1 | last post by:
What is WebLogic Admin Training? WebLogic Admin Training is a specialized program designed to equip individuals with the skills and knowledge required to effectively administer and manage Oracle...
0
by: antdb | last post by:
Ⅰ. Advantage of AntDB: hyper-convergence + streaming processing engine In the overall architecture, a new "hyper-convergence" concept was proposed, which integrated multiple engines and...
0
by: Arjunsri | last post by:
I have a Redshift database that I need to use as an import data source. I have configured the DSN connection using the server, port, database, and credentials and received a successful connection...
0
hi
by: WisdomUfot | last post by:
It's an interesting question you've got about how Gmail hides the HTTP referrer when a link in an email is clicked. While I don't have the specific technical details, Gmail likely implements measures...
1
by: Matthew3360 | last post by:
Hi, I have been trying to connect to a local host using php curl. But I am finding it hard to do this. I am doing the curl get request from my web server and have made sure to enable curl. I get a...
0
BLUEPANDA
by: BLUEPANDA | last post by:
At BluePanda Dev, we're passionate about building high-quality software and sharing our knowledge with the community. That's why we've created a SaaS starter kit that's not only easy to use but also...
2
by: Ricardo de Mila | last post by:
Dear people, good afternoon... I have a form in msAccess with lots of controls and a specific routine must be triggered if the mouse_down event happens in any control. Than I need to discover what...
1
by: ezappsrUS | last post by:
Hi, I wonder if someone knows where I am going wrong below. I have a continuous form and two labels where only one would be visible depending on the checkbox being checked or not. Below is the...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.