Difference between type and class

Nikolaus Rath Nikolaus at rath.org
Thu Jul 31 13:59:58 EDT 2008


Maric Michaud <maric at aristote.info> writes:
>>> What the <type int> means is that int is not a user type but a
>>> builtin type, instances of int are not types (or classes) but common
>>> objects, so its nature is the same as any classes.
>>>
>>> The way it prints doesn't matter, it's just the __repr__ of any instance,
>>> and the default behavior for instances of type is to return '<class XX>',
>>> but it can be easily customized.
>>
>> But 'int' is an instance of 'type' (the metaclass):
>> >>> int.__class__
>>
>> <type 'type'>
>>
>> so it should also return '<class int>' if that's the default behavior
>> of the 'type' metaclass.
>>
>
> The fact that a class is an instance of type, which it is always true, doesn't 
> mean its metaclass is "type", it could be any subclass of type :

Yes, that is true. But it's not what I said above (and below).
'obj.__class__' gives the class of 'obj', so if 'int.__class__ is
type' then 'type' is the class of 'int' and 'int' is *not* an instance
of some metaclass derived from 'type'.

>> I think that to get '<type int>' one would have to define a new
>> metaclass like this:
>>
>> def type_meta(type):
>>     def __repr__(self)
>>          return "<type %s>" % self.__name__
>>
>> and then one should have int.__class__ is type_meta. But obviously
>> that's not the case. Why?
>>
>> Moreover:
>> >>> class myint(int):
>>
>> ...    pass
>> ...
>>
>> >>> myint.__class__ is int.__class__
>> True
>>
>> >>> int
>> <type 'int'>
>>
>> >>> myint
>> <class '__main__.myint'>
>>
>> despite int and myint having the same metaclass. So if the
>> representation is really defined in the 'type' metaclass, then
>> type.__repr__ has to make some kind of distinction between int and
>> myint, so they cannot be on absolute equal footing.
>
> You're right, type(int) is type, the way it renders differently is a
> detail of its implementation, you can do things with builtin types
> (written in C) you coudn't do in pure python, exactly as you
> couldn't write recursive types like 'object' and 'type'.


If it is just a matter of different rendering, what's the reason for
doing it like that? Wouldn't it be more consistent and straightforward
to denote builtin types as classes as well?

And where exactly is this different rendering implemented? Could I
write my own type (in C, of course) and make it behave like e.g.
'int'? I.e. its rendering should be different and not inherited to
subclasses:


>>> my_type
<strange_thing 'my_type'>
>>> a = my_type(42)
>>> a.__class__
<strange_thing 'my_type'>

>>> class derived(my_type):
>>>    pass
<class 'derived>

or would I have to change the implemention of 'type' for this (since
it contains the __repr__ function that renders the type)?


This is of course purely theoretical and probably without any
practical relevance. I'm if I just can't stop drilling, but I think
this is really interesting.


Best,


   -Nikolaus

-- 
 »It is not worth an intelligent man's time to be in the majority.
  By definition, there are already enough people to do that.«
                                                         -J.H. Hardy

  PGP fingerprint: 5B93 61F8 4EA2 E279 ABF6  02CF A9AD B7F8 AE4E 425C



More information about the Python-list mailing list