Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

type, object hierarchy?

3 views
Skip to first unread message

7stud

unread,
Feb 3, 2008, 10:36:15 PM2/3/08
to
print dir(type) #__mro__ attribute is in here
print dir(object) #no __mro__ attribute


class Mammals(object):
pass
class Dog(Mammals):
pass

print issubclass(Dog, type) #False
print Dog.__mro__

--output:--
(<class '__main__.Dog'>, <class '__main__.Mammals'>, <type 'object'>)


The output suggests that Dog actually is a subclass of type--despite
the fact that issubclass(Dog, type) returns False. In addition, the
output of dir(type) and dir(object):


['__base__', '__bases__', '__basicsize__', '__call__', '__class__',
'__cmp__', '__delattr__', '__dict__', '__dictoffset__', '__doc__',
'__flags__', '__getattribute__', '__hash__', '__init__',
'__itemsize__', '__module__', '__mro__', '__name__', '__new__',
'__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__',
'__subclasses__', '__weakrefoffset__', 'mro']

['__class__', '__delattr__', '__doc__', '__getattribute__',
'__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__',
'__repr__', '__setattr__', '__str__']

suggests that type inherits from object since type has all the same
attributes as object plus some additional ones. That seems to
indicate a hierarchy like this:


object
|
V
type
|
V
Mammals
|
V
Dog


But then why does issubclass(Dog, type) return False?

Jason

unread,
Feb 3, 2008, 11:06:18 PM2/3/08
to

In your example, Mammal is directly derived from object, and Dog is
directly derived from Mammal. Dog isn't derived from type, so it
isn't considered a subclass. However, Python does create an instance
of class 'type' for each class you define. That doesn't mean that
'type' is a superclass. Try "isinstance(Dog, type)": it will return
True.

Type does inherit from object, but that's not what you're deriving
from. The hierarchy that you're using is:

Dog
^
|
Mammal
^
|
object

As you notice, type isn't part of the object hierarchy for Dog.
That's why it doesn't show up in the MRO. If you want to make Dog a
subclass of type, you'd need to do:

>>> class Dog(Mammal, type):
... pass
...
>>> issubclass(Dog, type)
True

I don't know why'd you would want to do that, though.

--Jason

7stud

unread,
Feb 4, 2008, 12:28:31 AM2/4/08
to

From the docs:

issubclass(class, classinfo)
Return true if class is a subclass (direct or indirect) of classinfo.


7stud

unread,
Feb 4, 2008, 12:31:44 AM2/4/08
to
On Feb 3, 10:28 pm, 7stud <bbxx789_0...@yahoo.com> wrote:
> From the docs:
>
> issubclass(class, classinfo)
> Return true if class is a subclass (direct or indirect) of classinfo.


print issubclass(Dog, object) #True
print issubclass(type, object) #True
print issubclass(Dog, type) #False

Robert Kern

unread,
Feb 4, 2008, 12:59:09 AM2/4/08
to pytho...@python.org

And if you want to really blow your mind,

print isinstance(type, object) # True
print isinstance(object, type) # True

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco

I V

unread,
Feb 4, 2008, 1:31:33 AM2/4/08
to
On Sun, 03 Feb 2008 21:31:44 -0800, 7stud wrote:

> On Feb 3, 10:28 pm, 7stud <bbxx789_0...@yahoo.com> wrote:
>> From the docs:
>>
>> issubclass(class, classinfo)
>> Return true if class is a subclass (direct or indirect) of classinfo.
>
>
> print issubclass(Dog, object) #True

So Dog is a subclass of object

> print issubclass(type, object) #True

and type is also a subclass of object. But

print issubclass(object, type) # False

so

> print issubclass(Dog, type) #False

which is what you would expect - Dog is a subclass of object, and object
isn't a subclass of type, so Dog isn't a subclass of type either.

Arnaud Delobelle

unread,
Feb 4, 2008, 2:21:39 AM2/4/08
to

Are you suggesting a new axiom for propositional logic:

((P => Q) ^ (R => Q)) => (P => R) ?

I.e. in fruit logic: every orange is a fruit and every apple is a
fruit, therefore every orange is an apple.

--
Arnaud

Ben Finney

unread,
Feb 4, 2008, 2:32:07 AM2/4/08
to
Robert Kern <rober...@gmail.com> writes:

> And if you want to really blow your mind,
>
> print isinstance(type, object) # True
> print isinstance(object, type) # True

Not what I see here.

Python 2.4.4 (#2, Jan 3 2008, 13:39:07)
[GCC 4.2.3 20071123 (prerelease) (Debian 4.2.2-4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> issubclass(type, object)
True
>>> issubclass(object, type)
False

Python 2.5.2a0 (r251:54863, Jan 3 2008, 19:40:30)
[GCC 4.2.3 20071123 (prerelease) (Debian 4.2.2-4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> issubclass(type, object)
True
>>> issubclass(object, type)
False

--
\ "Ignorance more frequently begets confidence than does |
`\ knowledge." —Charles Darwin |
_o__) |
Ben Finney

Ben Finney

unread,
Feb 4, 2008, 2:39:52 AM2/4/08
to
Ben Finney <bignose+h...@benfinney.id.au> writes:

> Robert Kern <rober...@gmail.com> writes:
>
> > And if you want to really blow your mind,
> >
> > print isinstance(type, object) # True
> > print isinstance(object, type) # True
>
> Not what I see here.

Ah, you tricked me! The parent message to yours was talking about
'issubclass' but you switched to 'isinstance'.

Nothing to see here.

--
\ "Never do anything against conscience even if the state demands |
`\ it." —Albert Einstein |
_o__) |
Ben Finney

Terry Jones

unread,
Feb 4, 2008, 2:40:27 AM2/4/08
to Arnaud Delobelle, pytho...@python.org
>>>>> "Arnaud" == Arnaud Delobelle <arn...@googlemail.com> writes:

Arnaud> Are you suggesting a new axiom for propositional logic:
Arnaud> ((P => Q) ^ (R => Q)) => (P => R) ?

Arnaud> I.e. in fruit logic: every orange is a fruit and every apple is a
Arnaud> fruit, therefore every orange is an apple.

This is otherwise known as Winterson's law:

1. Every orange is a fruit
2. Every apple is a fruit

=> Oranges are not the only fruit

Terry

Terry Jones

unread,
Feb 4, 2008, 2:40:27 AM2/4/08
to Arnaud Delobelle, pytho...@python.org

Hrvoje Niksic

unread,
Feb 4, 2008, 2:49:53 AM2/4/08
to
7stud <bbxx78...@yahoo.com> writes:

> --output:--
> (<class '__main__.Dog'>, <class '__main__.Mammals'>, <type 'object'>)
>
> The output suggests that Dog actually is a subclass of type--despite
> the fact that issubclass(Dog, type) returns False.

What was it in the output that gave you the impression that Dog is a
subclass of type? The last entry is only for the "object" type, which
you already knew Dog was a subclass of.

>>> object
<type 'object'>
>>> type
<type 'type'>

Bruno Desthuilliers

unread,
Feb 4, 2008, 4:27:28 AM2/4/08
to
7stud a écrit :

> print dir(type) #__mro__ attribute is in here
> print dir(object) #no __mro__ attribute
>
>
> class Mammals(object):
> pass
> class Dog(Mammals):
> pass
>
> print issubclass(Dog, type) #False
> print Dog.__mro__
>
> --output:--
> (<class '__main__.Dog'>, <class '__main__.Mammals'>, <type 'object'>)
>
>
> The output suggests that Dog actually is a subclass of type

Nope. It suggests that Dog is a subclass of object (which is not really
surprising).


7stud

unread,
Feb 4, 2008, 4:35:41 AM2/4/08
to
On Feb 4, 12:49 am, Hrvoje Niksic <hnik...@xemacs.org> wrote:

> 7stud <bbxx789_0...@yahoo.com> writes:
> > --output:--
> > (<class '__main__.Dog'>, <class '__main__.Mammals'>, <type 'object'>)
>
> > The output suggests that Dog actually is a subclass of type--despite
> > the fact that issubclass(Dog, type) returns False.
>
> What was it in the output that gave you the impression that Dog is a
> subclass of type?
>

The fact that Dog.__mro__ produces any output at all--instead of
producing an error. object does not have an __mro__attribute, so
where did Dog inherit that attribute from? The output of dir(type)
shoes that type has an __mro__ attribute. Some of the evidence
suggests this might be the hierarchy:

object ---> type
|
V
Mammal
|
V
Dog


But since Dog seems to inherit __mro__ from type, that hierarchy does
not appear to be correct. Rather this hierarchy seems more likely:


object
|
V
type
|
V
Mammal
|
V
Dog

> And if you want to really blow your mind,
>
> print isinstance(type, object)  # True
> print isinstance(object, type)  # True
>

Yep, I investigated that before I posted. It doesn't seem to fit with
the latter hierarchy.

Hrvoje Niksic

unread,
Feb 4, 2008, 4:50:10 AM2/4/08
to
7stud <bbxx78...@yahoo.com> writes:

> On Feb 4, 12:49 am, Hrvoje Niksic <hnik...@xemacs.org> wrote:
>> 7stud <bbxx789_0...@yahoo.com> writes:
>> > --output:--
>> > (<class '__main__.Dog'>, <class '__main__.Mammals'>, <type 'object'>)
>>
>> > The output suggests that Dog actually is a subclass of type--despite
>> > the fact that issubclass(Dog, type) returns False.
>>
>> What was it in the output that gave you the impression that Dog is a
>> subclass of type?
>
> The fact that Dog.__mro__ produces any output at all--instead of
> producing an error. object does not have an __mro__attribute, so
> where did Dog inherit that attribute from? The output of dir(type)
> shoes that type has an __mro__ attribute.

I see some confusion.

For one, while Dog is not a subclass of type, it's certainly an
*instance* of type. All instances of type have an __mro__ instance,
including object, regardless of whether dir() is aware of it. (Try
object.__mro__, it evaluates just fine.)

Second, simply the fact that an object has an attribute doesn't say
anything about its chain of inheritance. The final word on
inheritance is the contents of attributes such as __bases__ (shallow)
and __mro__ (deep).

Steven D'Aprano

unread,
Feb 4, 2008, 6:06:11 AM2/4/08
to
On Mon, 04 Feb 2008 10:50:10 +0100, Hrvoje Niksic wrote:

> ...regardless of whether dir() is aware of it.

I've always thought that having dir(obj) return only some attributes of
obj, according to some arbitrary, implementation and version dependent
algorithm, was an ugly wart.

help(dir) =>
"Return an alphabetized list of names comprising (some of) the attributes
of the given object, and of attributes reachable from it:"


--
Steven

Eduardo O. Padoan

unread,
Feb 4, 2008, 7:05:09 AM2/4/08
to 7stud, pytho...@python.org

Mel

unread,
Feb 4, 2008, 9:10:21 AM2/4/08
to
Python 2.5.1 (r251:54863, Oct 5 2007, 13:36:32)
[GCC 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)] on linux2

Type "help", "copyright", "credits" or "license" for more information.
>>> issubclass (object, type)
False
>>> isinstance (object, type)
True

Christian Heimes

unread,
Feb 4, 2008, 9:48:17 AM2/4/08
to pytho...@python.org
7stud wrote:
> The output suggests that Dog actually is a subclass of type--despite
> the fact that issubclass(Dog, type) returns False. In addition, the
> output of dir(type) and dir(object):

No, type is the meta class of the class object:

>>> issubclass(object, type)
False
>>> isinstance(object, type)
True

As you can see object is not a subclass of type but an instance of type.
This may look confusing at first but it's easy to explain. Like a class
is the blue print of an instance, a meta class is the blue print of a
class. In Python everything is a direct or indirect instance of type.

o = someobject
while o is not type:
o = type(o)
print o

The code will eventually print "type".

Christian

Jason

unread,
Feb 4, 2008, 10:25:57 AM2/4/08
to

Yes. That is exactly what is expected.

Dog is not subclassed from type. It is subclassed from Mammals, which
is subclassed from object.

Dog is, however, an instance of type. This is true of all new-style
Python classes.

All of Python's classes are objects. They have to be an instance of /
something/. New-style classes are instances of the class type. That
doesn't mean that they are considered subclasses from class type.
This means that the Dog object has all the methods, properties, and
class data that the class type has. Class type is Dog's metaclass --
the class of the class.

If you create an instance of Dog, you can access the various class
attributes that Dog has through the instance. It doesn't mean that
the instance of Dog is subclassed from Dog.

>>> terrier = Dog()
>>> issubclass(terrier, Dog)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: issubclass() arg 1 must be a class

In Python, you can create a subclass of class type. This isn't very
useful in most cases. If you set the __metaclass__ magick attribute,
however, your class object will be an instance of the class referred
to by that attribute. This lets you experiment with the way classes
are created and how the MRO works, and lets you break Python at a
pretty low level. For example:

>>> class NewTalky(type):
... def __new__(*args, **keyargs):
... print "I am called when Python creates a class whose
metaclass is me."
... print "I am responsible for creating a class object."
... print "My ordered arguments:", args
... print "My keyword arguments:", keyargs
... classObject = type.__new__(*args, **keyargs)
... print "The result of type.__new__():", classObject
... return classObject
...
>>> class Reptile(object):
... __metaclass__ = NewTalky
...
I am called when Python creates a class whose metaclass is me.
I am responsible for creating a class object.
My ordered arguments: (<class '__main__.NewTalky'>, 'Reptile', (<type
'object'>,), {'__module__': '__main__', '__metaclass__': <class
'__main__.NewTalky'>})
My keyword arguments: {}
The result of type.__new__(): <class '__main__.Reptile'>
>>>
>>> type(Dog) # Dog is an instance of class type
<type 'type'>
>>> type(Reptile) # Reptile is an instance of class NewTalky
<class '__main__.NewTalky'>
>>>
>>> issubclass(Reptile, type) # Reptile is not subclassed from type...
False
>>> issubclass( type(Reptile), type ) # ...but NewTalky is
True
>>> issubclass( type(Dog), type )
True
>>>


Again, everything in Python is an object. Your Python classes are
class objects. They are instances of the class type. In the first
example above, terrier is an instance of class Dog, but is not a
subclass of class Dog. Similarly, Dog is an instance of class type,
not a subclass of class type. Since class Dog is an instance of class
type, class type is considered to be Dog's metaclass.

You can create your own metaclasses. To quote another Pythoneer, if
you think you need a metaclass, you probably don't. If you know you
need a metaclass, you definitely do not need a metaclass. They are
tricky and mind-bending.

Hope this helps clear things up for you.

--Jason

7stud

unread,
Feb 4, 2008, 2:01:52 PM2/4/08
to
Thanks.

Steve Holden

unread,
Feb 4, 2008, 4:46:47 PM2/4/08
to pytho...@python.org
Christian Heimes wrote:

> 7stud wrote:
>> The output suggests that Dog actually is a subclass of type--despite
>> the fact that issubclass(Dog, type) returns False. In addition, the
>> output of dir(type) and dir(object):
>
> No, type is the meta class of the class object:
>
>>>> issubclass(object, type)
> False
>>>> isinstance(object, type)
> True
>
> As you can see object is not a subclass of type but an instance of type.
> This may look confusing at first but it's easy to explain. Like a class
> is the blue print of an instance, a meta class is the blue print of a
> class. In Python everything is a direct or indirect instance of type.
>
This might be helpful is the phrase "indirect instance" had any meaning
whatseover ;-)

> o = someobject
> while o is not type:
> o = type(o)
> print o
>
> The code will eventually print "type".
>

Except, of course, when someobject is type, when it won't print anything
at all.

regards
Steve
--
Steve Holden +1 571 484 6266 +1 800 494 3119
Holden Web LLC http://www.holdenweb.com/

0 new messages