On Feb 3, 10:31 pm, 7stud <[EMAIL PROTECTED]> wrote: > On Feb 3, 10:28 pm, 7stud <[EMAIL PROTECTED]> 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 -- http://mail.python.org/mailman/listinfo/python-list