Using descriptors
Mike C. Fletcher
mcfletch at rogers.com
Fri Nov 1 05:21:13 EST 2002
This is really much easier if you look first at the idea of a property,
and then later look at the ideas of pre and post conditions. So let's
take a look at the idea of a property:
A property can be thought of as a well-defined interaction mechanism
which provides a particular attribute for a particular class. The
property's operation is such that any attempt to access the attribute
using standard dotted notation (x.y.z) will trigger the property
interface to accomplish the interaction. A descriptor is merely an
abstraction of this concept, so that it can include such constructs as
static and class methods.
Here's a simple example:
class x(object):
def get_x( self, ):
print 'get x'
return (self._x,) # "wraps" the value on access
def set_x( self, value ):
print 'set x'
self._x = value * 3 # modifies the value on storage
x = property( get_x, set_x )
def __getattribute__( self, key ):
print 'get attribute', key
return object.__getattribute__( self, key )
r = x()
r.x = 3
print r.x
which prints out:
P:\temp>propdemo.py
set x
get attribute x
get x
get attribute _x
(9,)
Now here is where the distinction comes in regarding your example. In
your example, you do something very much like this:
class x(object):
d = SomeObject()
now in this case, what you've done is to create a class attribute which
is currently storing an instance of a class. The object stored in d
does not respond to the descriptor protocol. Conceptually, this class
attribute is being defined with a descriptor/property (which is never
actually created as far as I know, for efficiency reasons) which simply
hands back the instance which was set (i.e. it obeys the standard python
attribute semantics).
Where the idea of wrapping would come in is if you are interested in
being able to set any generic object through x.y = something and have
that generic object be wrapped in some particular functional wrapper
when accessed later via x.y . In the example above, imagine that
instead of wanting to wrap the integer with a tuple, we wanted instead
to return the integer as a special sub-class of integer which supports
rational division. We could define a descriptor which intercepts the
calls to always store a simple integer, but to always provide a wrapped
integer (which could be important for making pickling efficient).
Basically, for what you're doing, there is no need to use descriptors at
all. Simply wrapping your functions would be a perfectly acceptable
approach, and it would have the added benefit of running on almost any
python version likely to be in service.
Hope this makes sense, it's past five o'clock in the morning, so I may
not be particularly coherent at the moment.
Enjoy yourself,
Mike
AndrĂ³g i Ngaurwaith wrote:
>Mike Fletcher <mcfletch at rogers.com> wrote in message news:<cAUv9.119528$Q3S.60747 at news01.bloor.is.net.cable.rogers.com>...
>
>
>>You haven't, in your example, used any descriptors (explicitly). A
>>descriptor would (for instance) automatically wrap whatever was stored
>>in "testMethod" with the appropriate pre and post conditions. For
>>instance, a staticmethod descriptor wraps a function for access such
>>that the function is returned un-changed, a classmethod wraps a function
>>for access such that the function is passed a pointer to the class when
>>called, etceteras.
>>
>>
>
>Hmm... I don't really understand the distinction. What is it about
>descriptors that make them different from other classes (such as I
>used in the example)? To aid my understanding, would it be possible
>for you to give a definition for or some code illustrating this
>"wrapping"?
>
>
...
>Pre- and post-conditions are not actually what I'm after here; I'm
>trying to implement a way of transparently getting information (method
>name, parameters) about some method calls (for uses such as logging,
>etc), without having to add the code into the method.
>
>Andrew
>
>
_______________________________________
Mike C. Fletcher
Designer, VR Plumber, Coder
http://members.rogers.com/mcfletch/
More information about the Python-list
mailing list