type, object hierarchy?

Jason tenax.raccoon at gmail.com
Mon Feb 4 10:25:57 EST 2008


On Feb 3, 10:31 pm, 7stud <bbxx789_0... at yahoo.com> wrote:
> On Feb 3, 10:28 pm, 7stud <bbxx789_0... at 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

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



More information about the Python-list mailing list