[EMAIL PROTECTED] a écrit : > Hello everyone, > > I'm trying to do seemingly trivial thing with descriptors: have > another attribute updated on dot access in object defined using > descriptors. > > For example, let's take a simple example where you set an attribute s > to a string and have another attribute l set automatically to its > length. > >>>> class Desc(str): > def __init__(self,val): > self.s=val > self.l=len(val) > print "creating value: ", self.s > print "id(self.l)", id(self.l) > def __set__(self, obj, val): > self.s=val > self.l=len(val) > print "setting value:", self.s, "length:", self.l > def __get__(self, obj, type=None): > print "getting value:", self.s, "length:", self.l > return self.l > > >>>> class some(str): > m=Desc('abc') > l=m.l
First point : I don't get why Desc and some derive from str. Second point: I don't get why you're storing the value and it's length in the descriptor itself - obviously, you can't expect one descriptor instance to be mapped to 2 distinct attributes. Third point: you understand that, the way you wrote it, your descriptor will behave as a class (ie:shared) attribute, don't you. Fourth point: if you hope some.l to be rebound when m.l is, then you should learn Python basics before trying to jump into descriptors. The obvious, simple way to some your problem is to use a couple of properties: class Some(object): @apply def m(): def fget(self): return self._m def fset(self, val): self._m = val self._l = len(val) return property(**locals()) @apply def l(): def fget(self): return self._l def fset(self): raise AttributeError("%s.l is readonly" % self) def __init__(self, m): self.m = m Now if you absolutely insist on using custom descriptors, you'll need two of them: one to manage access to s, and the second to manage access to l (which btw is a very bad name): class DescS(object): def __init__(self, val): self._default = val def __set___(self, obj, val): obj._s = val obj._l = len(val) def __get__(self, obj, cls): if obj is None: return self # or self._default, or whatever try: return obj._s except AttributeError: return self._default class DescL(object): def __init__(self, descS): self._descS = descS def __get__(self, obj, cls): if obj is None: return self # or self._default, or whatever try: return obj._l except AttributeError: return len(self._descS._default) class Test(object): m = DescS('abc') l = DescL(m) (nb : not tested) -- http://mail.python.org/mailman/listinfo/python-list