type, object hierarchy?

Discussion in 'Python' started by 7stud, Feb 4, 2008.

  1. 7stud

    7stud Guest

    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?
     
    7stud, Feb 4, 2008
    #1
    1. Advertising

  2. 7stud

    Jason Guest

    On Feb 3, 8:36 pm, 7stud <> wrote:
    > 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:

    >>> class Dog(Mammal, type):

    .... pass
    ....
    >>> issubclass(Dog, type)

    True

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

    --Jason
     
    Jason, Feb 4, 2008
    #2
    1. Advertising

  3. 7stud

    7stud Guest

    On Feb 3, 9:06 pm, Jason <> wrote:
    > On Feb 3, 8:36 pm, 7stud <> wrote:
    >
    >
    >
    > > 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.  


    From the docs:

    issubclass(class, classinfo)
    Return true if class is a subclass (direct or indirect) of classinfo.
     
    7stud, Feb 4, 2008
    #3
  4. 7stud

    7stud Guest

    On Feb 3, 10:28 pm, 7stud <> 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
     
    7stud, Feb 4, 2008
    #4
  5. 7stud

    Robert Kern Guest

    7stud wrote:
    > On Feb 3, 10:28 pm, 7stud <> 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


    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
     
    Robert Kern, Feb 4, 2008
    #5
  6. 7stud

    I V Guest

    On Sun, 03 Feb 2008 21:31:44 -0800, 7stud wrote:

    > On Feb 3, 10:28 pm, 7stud <> 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.
     
    I V, Feb 4, 2008
    #6
  7. On Feb 4, 5:31 am, 7stud <> wrote:
    > On Feb 3, 10:28 pm, 7stud <> 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


    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
     
    Arnaud Delobelle, Feb 4, 2008
    #7
  8. 7stud

    Ben Finney Guest

    Robert Kern <> 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, Feb 4, 2008
    #8
  9. 7stud

    Ben Finney Guest

    Ben Finney <> writes:

    > Robert Kern <> 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
     
    Ben Finney, Feb 4, 2008
    #9
  10. 7stud

    Terry Jones Guest

    >>>>> "Arnaud" == Arnaud Delobelle <> 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, Feb 4, 2008
    #10
  11. 7stud

    Terry Jones Guest

    >>>>> "Arnaud" == Arnaud Delobelle <> 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, Feb 4, 2008
    #11
  12. 7stud <> 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'>
     
    Hrvoje Niksic, Feb 4, 2008
    #12
  13. 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).
     
    Bruno Desthuilliers, Feb 4, 2008
    #13
  14. 7stud

    7stud Guest

    On Feb 4, 12:49 am, Hrvoje Niksic <> wrote:
    > 7stud <> 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.
     
    7stud, Feb 4, 2008
    #14
  15. 7stud <> writes:

    > On Feb 4, 12:49 am, Hrvoje Niksic <> wrote:
    >> 7stud <> 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).
     
    Hrvoje Niksic, Feb 4, 2008
    #15
  16. 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
     
    Steven D'Aprano, Feb 4, 2008
    #16
  17. On Feb 4, 2008 1:36 AM, 7stud <> wrote:
    > 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)

    --
    http://www.advogato.org/person/eopadoan/
    Bookmarks: http://del.icio.us/edcrypt
     
    Eduardo O. Padoan, Feb 4, 2008
    #17
  18. 7stud

    Mel Guest

    7stud wrote:
    > On Feb 3, 10:28 pm, 7stud <> 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

    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
     
    Mel, Feb 4, 2008
    #18
  19. 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
     
    Christian Heimes, Feb 4, 2008
    #19
  20. 7stud

    Jason Guest

    On Feb 3, 10:31 pm, 7stud <> wrote:
    > On Feb 3, 10:28 pm, 7stud <> 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


    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
     
    Jason, Feb 4, 2008
    #20
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. John McC
    Replies:
    2
    Views:
    470
    Harald Hein
    Aug 20, 2003
  2. =?iso-8859-1?B?bW9vcJk=?=

    The hierarchy of the type is inconsistent

    =?iso-8859-1?B?bW9vcJk=?=, Jan 6, 2006, in forum: Java
    Replies:
    5
    Views:
    44,849
  3. Joel
    Replies:
    4
    Views:
    9,274
    John Harrison
    Oct 11, 2004
  4. Marco Nef
    Replies:
    7
    Views:
    531
    Grizlyk
    Jan 26, 2008
  5. kmw
    Replies:
    5
    Views:
    1,864
    James Kanze
    Oct 29, 2009
Loading...

Share This Page