Re: python object model

Mark Lutz (mlutz@KaPRE.COM)
Thu, 25 Aug 1994 09:40:23 +0700


> On the whole, I liked your presentation of metaclasses for Python,
> but you actually made it a bit trickier than it needs to be. Here's
> my take on how you'd implement a metaobject protocol for Python.
>
> First, some important observations (and vocabulary groundwork):
>
> an object is an instance of a class
> a class is an instance of a metaclass
> but a metaclass is just a class

But why not even simpler, like this:

an object is an instance of a class

and any class can define specially-named methods to intercept class
member access [see my prior post]. No special rules at all.

> Given this, a Python programmer could create new metaclasses by subclassing,
> as follows. To borrow Matt's example,
>
> class SMART_CLASS(CLASS):
> def __callmethod__(self, meth, *args):
> print "calling method", meth, "with", args
> # really call the method
> apply(meth, self + args)
>
> There's only one place the syntax would need to be changed and that
> is to indicate that a class is an instance of a particular metaclass.
> Again, to borrow Matt's example:
>
> class SmartRect is SMART_CLASS:
> def __init__(self, color):
> self.color = color
>
> def getcolor(self):
> return self.color
>
> Omitting the "is" clause is equivalent to "is CLASS".

But again, why not just this:

class SMART_CLASS: # a normal superclass
def __callmethod__(self, meth, *args):
print "calling method", meth, "with", args
apply(meth, self + args)

class SmartRect(SMART_CLASS): # normal class inheritance
def getcolor(self): # calls inherited __callmethod__
return self.color

No 'CLASS', 'is', 'metaclass', special inheritance rules, etc.


> SmartRect = SMART_CLASS().init()
> SmartRect.addMethod(__init__, <parsed version of __init__>)
> SmartRect.addMethod(getcolor, <parsed version of getcolor>)

Which is just normal class creation, right?

One (hopefully silly) issue in your example: how do we stop the cycle,
when you "apply(meth, self + args)" to "really call the method"? At
first glance, it seems that the apply() call would call getcolor()
again, which would call __callmethod__(), which would call apply()...
There would have to be some mechanism to avoid recalling the 'meta'
methods again [we can't make apply() avoid the meta's, since that would
make apply() non-orthogonal; maybe just setting a flag to detect that
we're already in a 'meta' method...].

> Matt asks why you would want to have a metaobject protocol. Unsurprisingly,
> this question has the same answer as the question, "In an OOP language,
> why would you want to create a subclass of a class?"
>
> * to change its implementation (by adding data items)
> * to change its behavior in a compatible way (by overriding methods)
> * to suppliment its behavior (by adding methods)

You've just defined OOP using normal classes in Python; why not just
use the existing 'class'?

Mark Lutz