Why property works only for objects?
Bruno Desthuilliers
bdesth.quelquechose at free.quelquepart.fr
Fri Mar 10 21:52:04 EST 2006
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)
More information about the Python-list
mailing list