Talk about PEP 213, which is related and can be (mostly) implemented

using the __findattr__() hook.
This commit is contained in:
Barry Warsaw 2000-12-02 04:11:32 +00:00
parent 64195d490d
commit e9ae8a5694
1 changed files with 66 additions and 3 deletions

View File

@ -110,6 +110,16 @@ Key Differences with the Existing Protocol
is used.
Related Work
PEP 213 [9] describes a different approach to hooking into
attribute access and modification. The semantics proposed in PEP
213 can be implemented using the __findattr__() hook described
here, with one caveat. The current reference implementation of
__findattr__() does not support hooking on attribute deletion.
This could be added if it's found desirable. See example below.
Examples
One programming style that this proposal allows is a Java
@ -368,9 +378,9 @@ Examples
assert 0, 'AttributeError expected'
And finally, C++-like access control can also be accomplished,
although less cleanly because of the difficulty of figuring out
what method is being called from the runtime call stack:
C++-like access control can also be accomplished, although less
cleanly because of the difficulty of figuring out what method is
being called from the runtime call stack:
import sys
import types
@ -520,6 +530,58 @@ Examples
assert b.getname() == 'A'
Here's an implementation of the attribute hook described in PEP
213 (except that hooking on attribute deletion isn't supported by
the current reference implementation).
class Pep213:
def __findattr__(self, name, *args):
hookname = '__attr_%s__' % name
if args:
op = 'set'
else:
op = 'get'
# XXX: op = 'del' currently not supported
missing = ()
meth = getattr(self, hookname, missing)
if meth is missing:
if op == 'set':
return setattr(self, name, *args)
else:
return getattr(self, name)
else:
return meth(op, *args)
def computation(i):
print 'doing computation:', i
return i + 3
def rev_computation(i):
print 'doing rev_computation:', i
return i - 3
class X(Pep213):
def __init__(self, foo=0):
self.__foo = foo
def __attr_foo__(self, op, val=None):
if op == 'get':
return computation(self.__foo)
elif op == 'set':
self.__foo = rev_computation(val)
# XXX: 'del' not yet supported
x = X()
fooval = x.foo
print fooval
x.foo = fooval + 5
print x.foo
# del x.foo
Reference Implementation
The reference implementation, as a patch to the Python core, can be
@ -537,6 +599,7 @@ References
[6] http://www.python.org/doc/essays/metaclasses/
[7] http://www.foretec.com/python/workshops/1998-11/dd-ascher-sum.html
[8] http://www.python.org/doc/howto/rexec/rexec.html
[9] http://python.sourceforge.net/peps/pep-0213.html
Copyright