Hooks, aspect-oriented programming, and design by contract
aleax at aleax.it
Thu Jan 24 08:08:25 EST 2002
"Huaiyu Zhu" <huaiyu at gauss.almadan.ibm.com> wrote in message
news:slrna4u8n5.1ec.huaiyu at gauss.almadan.ibm.com...
> >I also point out that I don't know how to switch metaclasses dynamically,
> >temporarily and "retroactively" (i.e. so that already-existing instances
> If you let class A be derived from another class C, which itself is an
> instance of a metaclass, then these aspects discussed above become the
> properties of the metaclass, so you can achieve similar effect by using
Yes, and you can also affect the metaclass in different ways, not just
by inheritance. Most directly, if A's body sets a class attribute
__metaclass__, the attribute's value will be used as A's metaclass;
if A has no bases, a global (module-level) variable __metaclass__, if
defined, will be used; last-ditch default is currently types.ClassType.
> What you claim don't know is whether the changes to the metaclass can
> objects a and b after they have already been constructed. Or, IOW,
> the metaclass is "doubly dynamic" in the sense that changes to it not only
> affect the class A at the time it is created, but also all the methods of
> when they are used.
> Is the above description essentially right?
Not exactly -- what I was trying to communicate was: once I have created
class A with metaclass M1, I don't know if I can switch A's metaclass to
be M2 instead, with all the above constraints.
Actually, it's not a doubt whether it can CURRENTLY be done:
>>> class M1(type): pass
>>> class A:
... __metaclass__ = M1
>>> class M2(type): pass
it's easy to determine that, yes, a class's __class__ CAN currently
be re-bound as above. Rather, my doubt is whether this is just a
current side effect of the 2.2 implementation, of the kind that can
just disappear at any time, or whether it IS dynamic by design.
Right now, i.e. wrt 2.2 and future versions, I don't really know any
more what dynamic effects are INTENDED to work, and which ones just
HAPPEN to work right now but are meant to break at any time. The PEPs
are pretty mysterious on the subject, claiming undefined status for
most of the things I'd like to do. So, maybe, the issue is still
undecided, in which case my "not knowing" is not easily remedied:-).
> If the metaclasses are "dynamic enough", wouldn't it be possible for it to
> decide, at the time when its instances (ie classes) are created, to leave
> hooks in their methods? Such hooks would then enable aspects of these
> method calls to be changed later.
Quite apart from the "runtime switchability" of metaclasses, it's
surely feasible for a metaclass's __init__, which is the spot that
is responsible for creating the classes that instantiate the
metaclass, to "place hooks" as it wishes (getting *inside* the
methods would presumably require some deep bytecode hacks, but
AOP is normally satisfied with working "around" the methods
anyway). Different stuff could then be "hung" to the hooks at
different times, for any such "hook-augmented" class.
I believe, for example, one precious distinction might be between
calls to class A's methods that come "from inside" versus calls
that come "from the outside"; a class's invariant for example only
needs to be checked around calls "from the outside" -- the
class's own methods are allowed to temporarily alter the invariant
while they only call each other. A metaclass might, hypothetically,
build a class that takes this distinction into account, allowing
more effective aspecting (selectively on "outwards-methods"
boundaries). This needs not involve metaclass-switching...
> Here's a newbie question to aspect oriented experts: is the set of aspects
> that can be changed predefined? If so, it seems to me that in principle
> metaclass could do at least what aspect oriented approach could do.
> I know little about either aspect oriented programming or the current
> of Python metaclasses, so I may be way off base here.
More information about the Python-list