> Of course, you could wrap a protected class in
> an empty dummy class, and route approved accesses to the associated real
> class, but it's inconvenient.
which was probably too strong: your examples (particularly Files.py) elegantly
demonstrate the utility of such a technique. One need not hand-code methods to
wrap _each_ operation supported by a built-in type; rather, a dummy proxy class
catches the accesses and routes them to a local instance of the real class/type.
Further, there's no need to have the users of the class call some special method
that does the routing [file.call('read', ..) instead of file.read(..)]. So, you
can access a file's methods like you would normally, but its also a specializable
class, and you don't need to manual wrap each method (or even know what methods
the type provides). Good Stuff!
Your approach is _much_ better than manual/exhaustive wrapper coding, or manual
routing methods.
I'm not sure I have an opinion on the use of 'pseudo' members, as shown in your
'Square.py' example. I'm already used to using parenthesis to fetch a member's
value; your use of __getattr__ to fire off computation when a pseudo method is
accessed ('object.area' triggers a method to compute the value) avoids typing
parenthesis after a member name. Definately convenient, but not a big deal to
me (but then I've already been corrupted by C++ :-0).
As far as catching access to ALL members (even existing ones, which don't raise
AttributeError), I'd also like to soften my position some: it's really NOT very
inconvenient to define a dummy/proxy class to catch member accesses and pass
valid ones on to a real class instance made by the constructor. In fact, this
would probably make it simpler to automate things like access restrictions--
a preprocessor could generate the proxy class wrappers automatically.
No complaints here...
Mark Lutz