[Python-Dev] PEP 231, __findattr__()
Guido van Rossum
guido@python.org
Mon, 04 Dec 2000 18:16:17 -0500
I'm unconvinced by the __findattr__ proposal as it now stands.
- Do you really think that JimF would do away with ExtensionClasses if
__findattr__ was intruduced? I kinda doubt it. See [*footnote].
It seems that *using* __findattr__ is expensive (even if *not* using
is cheap :-).
- Why is deletion not supported? What if you want to enforce a policy
on deletions too?
- It's ugly to use the same call for get and set. The examples
indicate that it's not such a great idea: every example has *two*
tests whether it's get or set. To share a policy, the proper thing
to do is to write a method that either get or set can use.
- I think it would be sufficient to *only* use __findattr__ for
getattr -- __setattr__ and __delattr__ already have full control.
The "one routine to implement the policy" argument doesn't really
hold, I think.
- The PEP says that the "in-findattr" flag is set on the instance.
We've already determined that this is not thread-safe. This is not
just a bug in the implementation -- it's a bug in the specification.
I also find it ugly. But if we decide to do this, it can go in the
thread-state -- if we ever add coroutines, we have to decide on what
stuff to move from the thread state to the coroutine state anyway.
- It's also easy to conceive situations where recursive __findattr__
calls on the same instance in the same thread/coroutine are
perfectly desirable -- e.g. when __findattr__ ends up calling a
method that uses a lot of internal machinery of the class. You
don't want all the machinery to have to be aware of the fact that it
may be called with __findattr__ on the stack and without it. So
perhaps it may be better to only treat the body of __findattr__
itself special, as Moshe suggested. What does Jython do here?
- The code examples require a *lot* of effort to understand. These
are complicated issues! (I rewrote the Bean example using
__getattr__ and __setattr__ and found no need for __findattr__; the
__getattr__ version is simpler and easier to understand. I'm still
studying the other __findattr__ examples.)
- The PEP really isn't that long, except for the code examples. I
recommend reading the patch first -- the patch is probably shorter
than any specification of the feature can be.
--Guido van Rossum (home page: http://www.python.org/~guido/)
[*footnote]
There's an easy way (that few people seem to know) to cause
__getattr__ to be called for virtually all attribute accesses: put
*all* (user-visible) attributes in a sepate dictionary. If you want
to prevent access to this dictionary too (for Zope security
enforcement), make it a global indexed by id() -- a
destructor(__del__) can take care of deleting entries here.