From: John Nagle on
I want to test whether an object is an instance of any user-defined
class. "isinstance" is less helpful than one would expect.

>>> import types
>>> class foo() : # define dummy class
.... pass
....
>>> x = foo()
>>>
>>> type(x)
<type 'instance'>
>>>
>>> isinstance(x, types.ClassType)
False
>>> isinstance(x, types.InstanceType)
True
>>> foo
<class __main__.foo at 0x004A2BD0>
>>> x
<__main__.foo instance at 0x020080A8>

So far, so good. x is an InstanceType. But let's try a
class with a constructor:

>>> class bar(object) :
.... def __init__(self, val) :
.... self.val = val
....
>>> b = bar(100)
>>> b
<__main__.bar object at 0x01FF50D0>
>>> isinstance(b, types.InstanceType)
False
>>> isinstance(b, types.ClassType)
False
>>>>>> bar
<class '__main__.bar'>

Without a constructor, we get an "instance". With a constructor,
we get an "object", one which is not an InstanceType.

One might think that testing for types.ObjectType would help. But
no, everything is an ObjectType:

>>> isinstance(1, types.ObjectType)
True
>>> isinstance(None, types.ObjectType)
True

So that's useless.

I have to be missing something obvious here.

(CPython 2.6)

John Nagle
From: Ben Finney on
John Nagle <nagle(a)animats.com> writes:

> I want to test whether an object is an instance of any user-defined
> class. "isinstance" is less helpful than one would expect.

Right. The type hierarchy is now unified; there's essentially no
difference in later Python versions between user-defined types and
built-in types.

> So that's useless.

For what purpose?

> I have to be missing something obvious here.

Maybe if we know what you're trying to do, we can suggest a better way.

--
\ “Human reason is snatching everything to itself, leaving |
`\ nothing for faith.” —Saint Bernard, 1090–1153 |
_o__) |
Ben Finney
From: John Nagle on
On 6/22/2010 8:13 PM, Ben Finney wrote:
> John Nagle<nagle(a)animats.com> writes:
>
>> I want to test whether an object is an instance of any user-defined
>> class. "isinstance" is less helpful than one would expect.
>
> Right. The type hierarchy is now unified; there's essentially no
> difference in later Python versions between user-defined types and
> built-in types.

OK, now that I know that, there's no problem.

I'n doing something that involves program analysis through
introspection. More on this later.

John Nagle
From: Gabriel Genellina on
En Tue, 22 Jun 2010 23:45:07 -0300, John Nagle <nagle(a)animats.com>
escribi�:

> I want to test whether an object is an instance of any user-defined
> class. "isinstance" is less helpful than one would expect.
>
> >>> import types
> >>> class foo() : # define dummy class
> ... pass
> ...
> >>> x = foo()
> >>>
> >>> type(x)
> <type 'instance'>
> >>>
> >>> isinstance(x, types.ClassType)
> False
> >>> isinstance(x, types.InstanceType)
> True
> >>> foo
> <class __main__.foo at 0x004A2BD0>
> >>> x
> <__main__.foo instance at 0x020080A8>
>
> So far, so good. x is an InstanceType. But let's try a
> class with a constructor:
>
> >>> class bar(object) :
> ... def __init__(self, val) :
> ... self.val = val
> ...
> >>> b = bar(100)
> >>> b
> <__main__.bar object at 0x01FF50D0>
> >>> isinstance(b, types.InstanceType)
> False
> >>> isinstance(b, types.ClassType)
> False
> >>>>>> bar
> <class '__main__.bar'>
>
> Without a constructor, we get an "instance". With a constructor,
> we get an "object", one which is not an InstanceType.

That's not the relevant difference. In the first case, you don't inherit
from object; in the second one, you do.

foo is a "classic" class (or "old-style" class); x is an instance of foo,
its *type* is InstanceType, its *class* is foo. All instances of any other
classic class have the same type (InstanceType).

bar is a "new-style" class, b is an instance of bar, its type is bar, its
class is bar. class and type are equivalent for new style classes; things
are a lot more regular and predictable. In Python 3.x classic classes are
gone.

--
Gabriel Genellina

From: Thomas Jollans on
On 06/23/2010 08:39 AM, Satish Eerpini wrote:
>
>
> I want to test whether an object is an instance of any
> user-defined
> class. "isinstance" is less helpful than one would expect.
>
> >>> import types
> >>> class foo() : # define dummy class
> ... pass
> ...
> >>> x = foo()
> >>>
> >>> type(x)
> <type 'instance'>
> >>>
> >>> isinstance(x, types.ClassType)
> False
> >>> isinstance(x, types.InstanceType)
> True
> >>> foo
> <class __main__.foo at 0x004A2BD0>
> >>> x
> <__main__.foo instance at 0x020080A8>
>
> So far, so good. x is an InstanceType. But let's try a
> class with a constructor:
>
> >>> class bar(object) :
> ... def __init__(self, val) :
> ... self.val = val
> ...
> >>> b = bar(100)
> >>> b
> <__main__.bar object at 0x01FF50D0>
> >>> isinstance(b, types.InstanceType)
> False
> >>> isinstance(b, types.ClassType)
> False
> >>>>>> bar
> <class '__main__.bar'>
>
> well the same code on my side returns true when you run isinstance(b,
> types.InstanceType) even when the class has a constructor. Why is there
> a difference in the output when we are both using Cython 2.6 ?? (2.6.4
> to be exact)

I assume you mean CPython, not Cython.

As Gabriel said, the difference is that bar is a subclass of object. If
isinstance(bar(100), types.InstanceType), then you did not subclass
object, and get an old-style class.