[Python-3000] enhanced descriptors
tomer filiba
tomerfiliba at gmail.com
Sat Jun 10 10:55:17 CEST 2006
disclaimer: i'm not sure this suggestion is feasible to
implement, because of the way descriptors work, but
it's something we should consider adding.
----
as you may remember, in iostack, we said the position
property should act like the following:
f.position = <non-negative int> # absolute seek
f.position = <negative int> # relative-to-end seek
f.position += <int> # relative-to-current seek
so i wrote a data descriptor. implementing the first two is
easy, but the third version is tricky.
doing x.y += z on a data descriptor translates to
x.__set__(y, x.__get__(y) + z)
in my case, it means first tell()ing, adding the offset, and
then seek()ing to the new position. this works, of course,
but it requires two system calls instead of one. what i
wished i had was x.__iadd__(y, z)
so my suggestion is as follows:
data descriptors must define __get__ and __set__. if they
also define one of the inplace-operators (__iadd___, etc),
it will be called instead of first __get__()ing and then
__set__()ing.
however, the inplace operators would have to use a different
signature than the normal operators -- instead of
__iadd__(self, other)
they would be defined as
__iadd__(self, obj, value).
therefore, i suggest adding __set_iadd__, or something in
that spirit, to solve the ambiguity.
for example, my position descriptor would look like:
class PositionDesc(object):
def __get__(self, obj, cls):
if obj is None:
return self
return obj.tell()
def __set__(self, obj, value):
if value >= 0:
obj.seek(value, "start")
else:
obj.seek(value, "end")
def __set_iadd__(self, obj, value):
obj.seek(value, "curr")
...
p = f.position # calls __get__
f.position = 5 # calls __set__
f.position = -5 # calls __set__
f.position += 10 # calls __set_iadd__
now there are two issues:
* is it even possible to implement (without overcomplicating the
descriptors mechanism)?
* is it generally useful?
i can't answer the first question, but it would surely be useful
in iostack; and besides, for symmetry's sake, if x += y calls
x.__iadd__(y), it should be optimized for descriptors as well.
i'd hate having to do two system calls for something that can
be done with one using seek().
-tomer
More information about the Python-3000
mailing list