Can I run an operation on an object's attribute when reading?
Steven D'Aprano
steve at REMOVE-THIS-cybersource.com.au
Mon Jan 19 08:19:10 EST 2009
On Mon, 19 Jan 2009 04:04:23 -0800, Phillip B Oldham wrote:
> Is it possible to automatically run an operation on a object's attribute
> when reading? For instance, if I have the following:
>
> class Item(object):
> tags = ['default','item']
>
> item = Item()
>
> desc = item.tags
>
> When I'm reading the item.tags, I'd like to automagically have the value
> converted to a string, eg: "default item". I know I could write a getter
> to do this for me, but I'd like to avoid that if possible on this
> occasion.
When all you have is a hammer, everything looks like a nail... Why do you
have to read item.tags directly? Just write a function and call it
instead of direct attribute access. This is the simplest, easiest
solution with the fewest side-effects.
def get_tags(item):
return ' '.join(item.tags)
desc = get_tags(item)
If you don't like that solution, monkey-patch the class with a getter:
@property
def tags(self):
return " ".join(self._tags)
Item._tags = Item.tags
Item.tags = tags
This is dangerous, because other classes may expect Item.tags to be a
list. Better to create your own accessor method:
def get_tags(self):
return " ".join(self.tags)
Item.get_tags = get_tags
item = Item()
desc = item.get_tags()
If you don't like monkey-patching (and you probably shouldn't), then
write a proxy class that delegates to the original:
_Item = Item
class Item(object):
def __init__(self, *args):
self.__dict__['_item'] = _Item(*args)
@property
def tags(self):
return ' '.join(self._item.tags)
def __getattr__(self, attr):
return getattr(self._item, attr)
def __setattr__(self, attr, value):
setattr(self._item, attr, value)
I dare say there's a metaclass solution too, but I'm not crazy enough to
do that.
--
Steven
More information about the Python-list
mailing list