[Python-Dev] Type/class differences (Re: Sets: elt in dict, lst.include)

Guido van Rossum guido@digicool.com
Mon, 05 Feb 2001 13:37:39 -0500


> On Sun, Feb 04, 2001 at 11:47:26PM -0500, Guido van Rossum wrote:
> > Yes, I've often thought that we should be able to heal the split for
> > 95% by using a few well-aimed tricks like this.  Later...
> 
> I was playing around this weekend with the class/type problem.
> Without too much effort I had an interpreter that could to things
> like this:
> 
>     >>> class MyInt(type(1)):
>     ...     pass
>     ...
>     >>> i = MyInt(10)
>     >>> i
>     10
>     >>> i + 1
>     11

Now, can you do things like this:

    >>> from types import *
    >>> class MyInt(IntType): # add a method
            def add1(self): return self+1

    >>> i = MyInt(10)
    >>> i.add1()
    11
    >>>

and like this:

    >>> class MyInt(IntType): # override division
            def __div__(self, other): return float(self) / other
            def __rdiv__(self, other): return other / float(self)

    >>> i = MyInt(10)
    >>> i/3
    0.33333333333333331
    >>> 

I'm not asking for adding new instance variables (slots), but that of
course would be the next step of difficulty up.

> The major changes were allowing PyClassObject to subclass types
> (ie. changing PyClass_Check(op) to (PyClass_Check(op) ||
> PyType_Check(op))), writing a _PyType_Lookup function, and making
> class_lookup use it.

Yeah, but that's still nasty.  We should strive for unifying PyClass
and PyType instead of having both around.

> The experiment has convinced me that we can allow subclasses of
> types quite easily without major changes.  It has also given me
> some ideas on "the right way" to solve this problem.  The rough
> scheme I can up yesterday goes like this:
> 
p>     PyObject {
>         int ob_refcnt;
>         PyClass ob_class;

(plus type-specific fields I suppose)

>     }
> 
>     PyClass {
>         PyObject_HEAD
>         char *cl_name;
>         getattrfunc cl_getattr;
>         PyMethodTable *cl_methods;
>     }
>         
>     PyMethodTable {
>         binaryfunc nb_add;
>         binaryfunc nb_sub;
>         ...
>     }
> 
> When calling a method on a object the interpreter would first
> check for a direct method and if that does not exist then call
> cl_getattr.  Obviously there are still a few details to be worked
> out. :-)

Yeah...  Like you should be able to ask for ListType.append and get an
unbound built-in method back, which can be applied to a list:

    ListType.append([], 1) === [].append(1)

And ditto for operators:

    IntType.__add__(1, 2) === 1+2

And a C API like PyNumber_Add(x, y) should be equivalent to using
x.__add__(y), too.

--Guido van Rossum (home page: http://www.python.org/~guido/)