overriding a property
Hrvoje Niksic
hniksic at xemacs.org
Wed Oct 20 11:25:53 EDT 2010
Lucasm <lordlucraft at gmail.com> writes:
> Thanks for the answers. I would like to override the property though
> without making special modifications in the main class beforehand. Is
> this possible?
That will not be easy. When you access obj.return_five, python looks up
'return_five' in type(obj) to see what the return_five property even
means. (See http://users.rcn.com/python/download/Descriptor.htm for
details of how this works.)
Since you can't change the source of A, you are left with two options:
you can monkey-patch A.return_five to make it optionally consult the
instance, or you can assign to instance's __class__ to make it point to
a subclass of A that implements a different 'return_five'. Both options
are fairly unpleasant, but I think I'd go with the first one.
Others have spelled out the __class__-changing variant. While
monkey-patching is not the cleanest of practices to adopt, in my mind it
still beats assigning to __class__. Here is an example:
# Wrap return_five so it supports per-instance customization, but
# without copy-pasting the original.
def wrap_return_five(orig):
@property
def wrapper(self):
if 'return_five' in self.__dict__:
return self.__dict__['return_five']
return orig.__get__(self, type(self))
return wrapper
>>> A.return_five = wrap_return_five(A.return_five)
>>> a = A()
>>> b = A()
>>> a.return_five
5
>>> a.__dict__['return_five'] = 10
>>> a.return_five
10
>>> b.return_five
5
If you want, you can make a.return_five itself settable, but I'll leave
that as an excercise for the reader.
More information about the Python-list
mailing list