Talk about PEP 213, which is related and can be (mostly) implemented
using the __findattr__() hook.
This commit is contained in:
parent
64195d490d
commit
e9ae8a5694
69
pep-0231.txt
69
pep-0231.txt
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue