The type/object distinction and possible synthesis of OOP and imperative programming languages

Steven D'Aprano steve+comp.lang.python at pearwood.info
Mon Apr 15 22:15:00 EDT 2013


On Mon, 15 Apr 2013 19:43:32 +0200, Antoon Pardon wrote:

> Op 15-04-13 12:11, Steven D'Aprano schreef:
> 
> 
>> Python's data model has always been 100% object oriented. Prior to the
>> "class/type" unification, it simply had *two distinct* implementations
>> of objects: types, which were written in C, and classes, which were
>> written in Python.
>>
>> After unification, the two kinds of object were no longer entirely
>> distinct -- you could then subclass types in Python code, using the
>> same "class" keyword as you would use for a pure-Python class.
>>
>> And starting with Python 3, the last vestiges of the distinction have
>> disappeared. Now, "class" and "type" are mere synonyms. Both built-in
>> types and custom classes use the same mechanism.
> 
> I had gotten my hopes up after reading this but then I tried:
> 
> 
> $ python3
> Python 3.2.3 (default, Feb 20 2013, 17:02:41) [GCC 4.7.2] on linux2
> Type "help", "copyright", "credits" or "license" for more information.
>  >>> class vslice (slice):
> ...   pass
> ...
> Traceback (most recent call last):
>    File "<stdin>", line 1, in <module>
> TypeError: type 'slice' is not an acceptable base type
> 
> 
> It seems types and classes are still not mere synonyms.


You are misinterpreting what you are reading. The mere fact that 
something cannot be subclassed doesn't mean anything. That's just a 
restriction put on the class by the implementation. It's not even clear 
that it is a guaranteed language restriction or a mere accident of 
implementation. With a bit of metaclass trickery, I could equally create 
a pure-Python class that cannot be easily subclassed.

The proof that types and classes are the same in Python 3 is simple:

py> class C:
...     pass
...
py> type(C) is type(int) is type(type) is type
True

The type of the pure-Python class is type itself.

However, even this can be bypassed, using a metaclass!

py> class D(metaclass=Meta):
...     pass
...
py> type(D) is type
False
py> issubclass(type(D), type)
True


So when using a metaclass, the type of the class is not necessarily type 
itself, but it will be a subclass of type.

This does not hold in Python 2.x, not for old-style "classic" classes. 
Classic classes are in a world of their own, distinct from types:

# Python 2
py> class C:
...     pass
...
py> type(C)
<type 'classobj'>
py> issubclass(type(C), type)
False



In Python 3, we can expect these two conditions to always hold:

* all instances are instances of object;

* all classes are instances of type.


Notice that this implies that type and object are circularly defined: 
object, being a class, is an instance of type, but type, being an object, 
is an instance of object:

py> isinstance(type, object)
True
py> isinstance(object, type)
True



These two conditions even apply to unsubclassable objects like slice:

py> isinstance(slice(1, 5, 2), object)
True
py> isinstance(slice, type)
True



-- 
Steven



More information about the Python-list mailing list