type, object hierarchy?

7

7stud

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?
 
J

Jason

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?

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:
.... pass
....True

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

--Jason
 
7

7stud

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:

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

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.  

From the docs:

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

7stud

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
 
R

Robert Kern

7stud said:
print issubclass(Dog, object) #True
print issubclass(type, object) #True
print issubclass(Dog, type) #False

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

I V

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.
 
A

Arnaud Delobelle

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

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.
 
B

Ben Finney

Robert Kern said:
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.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.False
 
B

Ben Finney

Ben Finney said:
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.
 
T

Terry Jones

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
 
T

Terry Jones

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
 
H

Hrvoje Niksic

7stud said:
--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.
<type 'type'>
 
B

Bruno Desthuilliers

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).
 
7

7stud

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.
 
H

Hrvoje Niksic

7stud said:
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).
 
S

Steven D'Aprano

...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:"
 
E

Eduardo O. Padoan

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?


Here you should find The Answer (tm):
http://www.cafepy.com/article/python_types_and_objects/python_types_and_objects.html

(Beautifully ilustrated, BTW)
 
M

Mel

7stud said:
print issubclass(Dog, object) #True
print issubclass(type, object) #True
print issubclass(Dog, type) #False
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.True
 
C

Christian Heimes

7stud said:
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:
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
 
J

Jason

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

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.
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:
.... 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
........ __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: {}


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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top