[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