[ZODB-Dev] Persistent-derived class instances always callable

Phillip J. Eby pje at telecommunity.com
Tue Oct 21 09:44:13 EDT 2003


At 11:34 PM 10/20/03 -0400, Shane Hathaway wrote:

>The fact that proxies are even possible in Python is a very neat trick.  I 
>hope that Python will explore how transparent proxies can/should 
>be.  Proxies solve major problems in OO design.  They are more interesting 
>than "aspects", another relatively new OO pattern, since proxies let you 
>cleanly modify the behavior of individual instances (without even changing 
>the instances), while aspects aren't so granular; aspects modify the 
>behavior of all instances of a given class.

That's not technically correct.  *Many* AOP implementations allow 
instance-specific modifications, including JAC and the various ObjectTeams 
implementations.  And at least in the case of JAC, they're implemented 
using proxies.  Heck, the whole "Composition Filters" school of AOP is 
based on proxies.

AOP is in as fragmented a state as OOP was back in the days when new 
experimental OO languages were springing up every month or so, and people 
are still putting forth ideas about what AOP *is*.  So, it's virtually 
impossible to say anything really specific about AOP right now.

But one way you can look at AOP, is that it's studying the theory of ways 
to specify modifications to objects.  If you look at it from that 
perspective, then designing individual proxies is a bit like working in 
assembly language: it's a low-level but infinitely flexible way to do 
things.  Most AOP research is about e.g. *composing* proxies, rule-driven 
ways to create proxies and so on.  Higher-level languages, in other 
words.  I think it's still going to be a while before there's a reasonable 
consensus of what AOP is, in the way that we now say things like 
encapsulation, inheritance, etc. are part of OOP.  (And note that people 
*still* disagree about what constitutes OOP precisely, even though there's 
sort of a vague consensus!)

(Btw, aspects aren't *that* new.  I remember reading papers on it back in 
1997, and research may go back even further.)


>I'm not concerned about ExtensionClass.  Everyone knows it breaks some 
>expectations and people work around that.  I'm concerned about the future 
>prospects for writing proxy-like classes (both in C and Python.)  The fact 
>that weakref chose the dual-type strategy makes me uneasy about writing 
>proxy classes; who knows what Python will add next that can't be emulated 
>by proxies?  I want to be sure Python continues to support proxies well.
>
>If callable() is the only thing that demands multiple proxy classes, 
>that's not too bad.  Let's not add any more.

You're missing something about new-style classes.  There's no need to limit 
yourself to static proxy types.  If you have an object with a 
heap-allocated type, you can create an on-the-fly, per-instance subclass, 
if you want, overriding precisely the behaviors you want.  Want it to be 
callable?  Set newtype.__call__.  Alternatively, if you want a separate 
proxy instance rather than in-place modification, loop through the "magic 
names" on the target class, and then assign values from your "all-purpose" 
proxy class.  If you have a particular C layout needed, create a C base 
class with the layout, and then a subclass with all the behavior slots.  To 
create your dynamic proxy, subclass the layout base, and then populate it 
with methods from the behavior class.

Granted, this doesn't help you if an object changes its own class on the 
fly, either pointing to a new class or adding methods to its existing 
class.  But, neither do the more traditional proxy techniques.

Also, almost forgot to mention...  __call__ (aka tp_call) is not the only 
type slot introspected by Python.  __set__ (aka tp_descr_set) and __iter__ 
(aka tp_iter) are also checked for various purposes, although the 
introspection functions aren't exposed to Python code.  __set__ is checked 
to determine if a descriptor is a "data descriptor", and __iter__ is 
checked to see whether an object is iterable.  And, these probably are not 
the only other slots being checked.

So, if you want to make *really* transparent proxies for any possible 
object type, you really need to be dynamically generating them already anyway.




More information about the ZODB-Dev mailing list