Michal Kwiatkowski a écrit : > Steven Bethard napisał(a): > >>>Is there any method of making descriptors on per-object basis? >> >>I'm still not convinced that you actually want to, but you can write >>your own descriptor to dispatch to the instance object (instead of the >>type): > > > Ok, this works for attributes I know a name of at class definition. What > about other situations? I could possibly want to have different sets of > attributes for instances of a class.
Then you want a different class for each different set of attributes. > Is it still possible to do? I don't > also like current solution, as it wraps things around, creating another > attribute ('_x') in the process. Aren't there any cleaner solutions? > > The problem is I have an instance of a given class (say BaseClass) and I > want it to implement some attribute accesses as method calls. I'm not a > creator of this object, so changing definition of BaseClass or > subclassing it is not an option. What you want is delegation. Which is pretty easy with Python, look at __getattr__ and __setattr__. > Code below doesn't work, but shows my > intention: > > # obj is instance of BaseClass > def get_x(self): > # ... > def set_x(self, value): > # ... > obj.x = property(get_x, set_x) class ObjWrapper(object): def __init__(self, obj): self.obj = obj # special case x def _get_x(self): return self.obj.x def _set_x(self, value): self.obj.x = value x = property(fget=_get_x, fset=_set_x) # default lookup, directly delegate to obj def __getattr__(self, name): return getattr(self.obj, name) def __setattr__(self, name, value): # this one is a bit more tricky # and I don't remember it right now, # but it's in the fine manual anyway obj = ObjWrapper(obj) obj.x # calls ObjWrapper._get_x() > Changing __setattr__/__getattr__ of an object also doesn't work for the > same reason: dictionary lookup is made only in class attributes, > ommiting object attributes. It's confusing, because writting obj.x and > obj.__getattribute__('x') gives a different results. There also seems > not to be any clear way to define methods for objects. Something like: > > class C(object): > pass > > def method(self): > return self.x > > c = c.x > c.method = method > c.method() # => AttributeError import types c.method = types.MethodType(method, c, c.__class__) > So another question arise. Is it possible to make function a method (so > it will receive calling object as first argument)? Yeps, just wrap it in a Method object (cf above) -- http://mail.python.org/mailman/listinfo/python-list