Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Can I run an operation on an object's attribute when reading?

Reply
Thread Tools

Can I run an operation on an object's attribute when reading?

 
 
Phillip B Oldham
Guest
Posts: n/a
 
      01-19-2009
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.

Any help would be great! Thanks.
 
Reply With Quote
 
 
 
 
Chris Rebert
Guest
Posts: n/a
 
      01-19-2009
On Mon, Jan 19, 2009 at 4:04 AM, Phillip B Oldham
<(E-Mail Removed)> 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.


Assuming I'm interpreting you correctly (you're going to have to use
something like a getter):

class Item(object):
def __init__(self):
self._tags = ['default', 'item']

@property
def tags(self):
return ' '.join(self._tags)

print Item().tags #==> default item

Cheers,
Chris

--
Follow the path of the Iguana...
http://rebertia.com
 
Reply With Quote
 
 
 
 
Phillip B Oldham
Guest
Posts: n/a
 
      01-19-2009
On Mon, Jan 19, 2009 at 12:15 PM, Chris Rebert <(E-Mail Removed)> wrote:
> Assuming I'm interpreting you correctly (you're going to have to use
> something like a getter):


Thanks, but I'm looking for a way to do it *without* using a getter as
I don't have easy access to the class (its being generated for me
elsewhere). Essentially I'd like to overwrite (if possible) the
default behavior when returning certain attributes on certain objects.
 
Reply With Quote
 
Chris Rebert
Guest
Posts: n/a
 
      01-19-2009
On Mon, Jan 19, 2009 at 4:22 AM, Phillip B Oldham
<(E-Mail Removed)> wrote:
> On Mon, Jan 19, 2009 at 12:15 PM, Chris Rebert <(E-Mail Removed)> wrote:
>> Assuming I'm interpreting you correctly (you're going to have to use
>> something like a getter):

>
> Thanks, but I'm looking for a way to do it *without* using a getter as
> I don't have easy access to the class (its being generated for me
> elsewhere). Essentially I'd like to overwrite (if possible) the
> default behavior when returning certain attributes on certain objects.


To my knowledge, you can't really "overwrite" that behavior without
editing the class (or how it's generated).
The next closest thing would be to write a proxy class that defines a
__getattr__ method implementing the semantics you want.

Cheers,
Chris

--
Follow the path of the Iguana...
http://rebertia.com
 
Reply With Quote
 
Michael Hartl
Guest
Posts: n/a
 
      01-19-2009
Phillip B Oldham schrieb:
> On Mon, Jan 19, 2009 at 12:15 PM, Chris Rebert <(E-Mail Removed)> wrote:
>
>> Assuming I'm interpreting you correctly (you're going to have to use
>> something like a getter):
>>

>
> Thanks, but I'm looking for a way to do it *without* using a getter as
> I don't have easy access to the class (its being generated for me
> elsewhere). Essentially I'd like to overwrite (if possible) the
> default behavior when returning certain attributes on certain objects.
> --
> http://mail.python.org/mailman/listinfo/python-list
>

You could still add the getter to the class after it has been defined if
that's your only problem with
using a getter:

class Item(object):
tags = ['default','item']

@property
def tags(self):
return ' '.join(self.tags)

setattr(Item, "Tags", tags)

print Item().Tags #==> default item


But I don't think there's a way to do it without a different name (here
"tags" - "Tags"), is there?
 
Reply With Quote
 
Steven D'Aprano
Guest
Posts: n/a
 
      01-19-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
 
Reply With Quote
 
Bruno Desthuilliers
Guest
Posts: n/a
 
      01-19-2009
Chris Rebert a écrit :
> On Mon, Jan 19, 2009 at 4:22 AM, Phillip B Oldham
> <(E-Mail Removed)> wrote:
>> On Mon, Jan 19, 2009 at 12:15 PM, Chris Rebert <(E-Mail Removed)> wrote:
>>> Assuming I'm interpreting you correctly (you're going to have to use
>>> something like a getter):

>> Thanks, but I'm looking for a way to do it *without* using a getter as
>> I don't have easy access to the class (its being generated for me
>> elsewhere). Essentially I'd like to overwrite (if possible) the
>> default behavior when returning certain attributes on certain objects.

>
> To my knowledge, you can't really "overwrite" that behavior without
> editing the class (or how it's generated).


Assuming it's really about a *class* object (not instances of it), *and*
it's a new-style class, it is possible:
class Foo(object):
def __init__(self):
self.tags = ['foo', 'bar']

def wrap_tag_access(cls):
def fset(obj, value):
obj._tags = value

def fget(obj):
print "do something here"
return obj._tags

cls.tags = property(fset=fset, fget=fget)
return cls

Foo = wrap_tag_access(Foo)
f = Foo()
print f.tags




> The next closest thing would be to write a proxy class that defines a
> __getattr__ method implementing the semantics you want.


If it's a "classic" class, then yes, it's probably the best thing to do.
 
Reply With Quote
 
Bruno Desthuilliers
Guest
Posts: n/a
 
      01-19-2009
Steven D'Aprano a écrit :
(snip)

> 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.


A sensible advice, but only relevant if this class instances are only
used by code the OP do control. Which may or not be the case.

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Boolean operation and arithmetic operation Buzz Lightyear C++ 10 08-12-2009 01:27 PM
I/O operation, file operation behaviou raan C++ 2 08-16-2007 07:13 PM
Does bit operation always work more efficiently than math operation? david ullua C Programming 13 03-01-2006 11:02 PM
can run javascript can't run vbscript - WHY duncan ASP .Net 2 10-27-2004 09:31 AM
The file 'bin\WebProj.dll' cannot be copied to the run directory. The requested operation cannot be performed on a file with a user-mapped section open. J Gao ASP .Net 0 07-28-2003 04:18 PM



Advertisments