Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Propert handler question

Reply
Thread Tools

Propert handler question

 
 
user@domain.invalid
Guest
Posts: n/a
 
      10-30-2003
Is there a way, from within a getter/setter method
linked to a propert, that I can tell which property
triggered the method?

This would be great, because I need a great number
of these properties, each having only slightly different
actions, which could be triggered correctly if
I knew the name of the property that was being accessed.

Thanks,

Toby

 
Reply With Quote
 
 
 
 
Stephen Horne
Guest
Posts: n/a
 
      10-31-2003
On Thu, 30 Oct 2003 20:52:28 GMT, http://www.velocityreviews.com/forums/(E-Mail Removed)lid wrote:

>Is there a way, from within a getter/setter method
>linked to a propert, that I can tell which property
>triggered the method?
>
>This would be great, because I need a great number
>of these properties, each having only slightly different
>actions, which could be triggered correctly if
>I knew the name of the property that was being accessed.


I don't think so, though I could be wrong.

I'd write one main getter/setter function with an extra parameter for
the property name, then add a whole bunch of noddy getter/setter
functions that provide that extra parameter. Or perhaps a number of
extra parameters - flags to control specific parts of the handlers -
would work better.


--
Steve Horne

steve at ninereeds dot fsnet dot co dot uk
 
Reply With Quote
 
 
 
 
John Roth
Guest
Posts: n/a
 
      10-31-2003

<(E-Mail Removed)> wrote in message
news:(E-Mail Removed) s.com...
> Is there a way, from within a getter/setter method
> linked to a propert, that I can tell which property
> triggered the method?
>
> This would be great, because I need a great number
> of these properties, each having only slightly different
> actions, which could be triggered correctly if
> I knew the name of the property that was being accessed.


The only thing that occurs to me is looking up the call
stack to find what was being accessed. Somehow, that
seems to be the wrong way to approach the problem,
though.

You might want to look at the __getattr__() and
___setattr() magic methods defined in the Python
Language Reference manual (section 3.3.3 in the
Python 2.2.3 manual set.) These are not the easiest
things in the world to program correctly, (setattr in
particular is prone to loops unless you do everything
exactly right) but they
might be what you need in this case, rather than
a boatload of properties.

John Roth
>
> Thanks,
>
> Toby
>



 
Reply With Quote
 
Bengt Richter
Guest
Posts: n/a
 
      10-31-2003
On Thu, 30 Oct 2003 20:52:28 GMT, (E-Mail Removed)lid wrote:

>Is there a way, from within a getter/setter method
>linked to a propert, that I can tell which property
>triggered the method?
>
>This would be great, because I need a great number
>of these properties, each having only slightly different
>actions, which could be triggered correctly if
>I knew the name of the property that was being accessed.
>

I think you might want to make a custom descriptor class whose
instances you can give names the same as the property they implement.
The get and set methods are the same, but have access to the name parameter
saved in the descriptor instance. E.g., (note that there are two instance "selves"
involved -- the self of the descriptor/property where the individual name is stored,
and the self of the object normally passed to a getter function, but here just
implemented in line, since it is the same for all the descriptor instances in this case.

The following might give you some ideas. The metaclass thing was just to avoid
definining the properties one by one like

class Test(object):
foo = NamedProp('foo')
bar = NamedProp('bar')
baz = NamedProp('baz')
...

(you said there might be a lot of them, so I thought __proplist__ = 'foo bar baz'.split()
would be easier and guarantee the matching of the names bound with the strings passed to the
NamedProp constructor).

A good writeup on the descriptor stuff is Raymond Hettinger's

http://users.rcn.com/python/download/Descriptor.htm

to whom thanks. Also you may want to read

http://www.python.org/2.2.2/descrintro.html

(Hope I haven't misled with the following. Caveat lector?

====< namedprop.py >================================================= ======
class NamedProp(property):
def __get__(pself, oself, otype=None):
"""NamedProp getter"""
if oself is None:
return pself
# implement shared getter code here
# note property instance pself, and object instance oself both available
return pself.name, oself._pval # example of value depending on both
def __set__(pself, oself, val):
"""NamedProp setter"""
# customize as desired
oself._pval = val
def __init__(pself, name):
"""Give property instance a name"""
pself.name = name

class MC_AddNamedProps(type):
"""Automate adding a list of named properties with shared getter/setter code"""
def __new__(cls, cname, cbases, cdict):
for name in cdict.get('__proplist__',[]):
cdict[name]=NamedProp(name)
return type.__new__(cls, cname, cbases, cdict)

class Test(object):
"""Example class with name-carrying properties"""
__metaclass__ = MC_AddNamedProps
__proplist__ = 'foo bar baz'.split()
def __init__(self, val=None): self._pval=val

def test():
t1 = Test(111)
print 't1:',t1
print 't1.foo => %r' % (t1.foo,)
print 't1.bar => %r' % (t1.bar,)
print 't1.baz => %r' % (t1.baz,)
print 't1.foo = <new value via t1.foo> =>'
t1.foo = '<new value via t1.foo>'
print 't1.foo => %r' % (t1.foo,)
print 't1.bar => %r' % (t1.bar,)
print 't1.baz => %r' % (t1.baz,)
if __name__ == '__main__':
test()
====< namedprop.py >================================================= ======

Result:

[22:35] C:\pywk\clp\descr>namedprop.py
t1: <__main__.Test object at 0x0090B310>
t1.foo => ('foo', 111)
t1.bar => ('bar', 111)
t1.baz => ('baz', 111)
t1.foo = <new value via t1.foo> =>
t1.foo => ('foo', '<new value via t1.foo>')
t1.bar => ('bar', '<new value via t1.foo>')
t1.baz => ('baz', '<new value via t1.foo>')

Regards,
Bengt Richter
 
Reply With Quote
 
Alex Martelli
Guest
Posts: n/a
 
      10-31-2003
(E-Mail Removed)lid wrote:

> Is there a way, from within a getter/setter method
> linked to a propert, that I can tell which property
> triggered the method?
>
> This would be great, because I need a great number
> of these properties, each having only slightly different
> actions, which could be triggered correctly if
> I knew the name of the property that was being accessed.


So use a closure. E.g, trivial example:

def prop(name):
def getter(self):
print 'getting', name
return getattr(self, '_'+name)
def setter(self, value):
print 'setting', name, 'to', value
return setattr(self, '_'+name, value)
return getter, setter

class WithProperties(object):
foo = property(*prop('foo'))
bar = property(*prop('bar'))
baz = property(*prop('baz'))

w = WithProperties()
w.foo = w.bar = 23
print w.foo, w.bar

will emit:

[alex@lancelot bo]$ python proe.py
setting foo to 23
setting bar to 23
getting foo
23 getting bar
23


Yes, this does require a double specification of the name -- as
an argument to prop AND as the thing you assign to in classbody.

Avoiding this requires black or at least dark-grayish magic, such
as (I've seen others already suggest somewhat-more-magic-yet
solutions requiring both custom metaclasses and custom descriptors,
this one at least makes do with a custom metaclass and a descriptor
_helper_ that gets turned into an ordinary property descriptor...:

class magicprop(object):
def __init__(self, name=''): self.name = name
def getter(self, other):
print 'getting', self.name
return getattr(other, '_'+self.name)
def setter(self, other, value):
print 'setting', self.name, 'to', value
return setattr(other, '_'+self.name, value)

class magicmeta(type):
def __new__(mcl, clasname, clasbase, clasdict):
for n, v in clasdict.items():
if not isinstance(v, magicprop): continue
v.name = n
clasdict[n] = property(v.getter, v.setter)
return type.__new__(mcl, clasname, clasbase, clasdict)

class magic: __metaclass__ = magicmeta

class WithProperties(magic):
foo = magicprop()
bar = magicprop()
baz = magicprop()

w = WithProperties()
w.foo = w.bar = 23
print w.foo, w.bar


this gives the same output as before.

If you do a lot of this you probably don't want to code the
getters and setters right inside the magicprop helper, of
course, but rather code them in the target class and pass
them to magicprop as you'd normally pass them to property.
No problem, actually...:

class magicprop(object):
def __init__(self, getter, setter, name=''):
self.name = name
self.getter = getter
self.setter = setter
def get(self, other):
return self.getter(other, self.name)
def set(self, other, value):
return self.setter(other, self.name, value)

class magicmeta(type):
def __new__(mcl, clasname, clasbase, clasdict):
for n, v in clasdict.items():
if not isinstance(v, magicprop): continue
v.name = n
clasdict[n] = property(v.get, v.set)
return type.__new__(mcl, clasname, clasbase, clasdict)

class magic: __metaclass__ = magicmeta

class WithProperties(magic):
def getter(self, name):
print 'getting', name
return getattr(self, '_'+name)
def setter(self, name, value):
print 'setting', name, 'to', value
setattr(self, '_'+name, value)
foo = magicprop(getter, setter)
bar = magicprop(getter, setter)
baz = magicprop(getter, setter)

w = WithProperties()
w.foo = w.bar = 23
print w.foo, w.bar


and again the output is as usual.


Alex

 
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
Event Handler that creates adds another event handler kaczmar2@gmail.com ASP .Net 1 02-22-2007 07:37 AM
How do fix: "Wrong number of arguments" / "invalid propert assignment"/ "Invalid argument" Java Guy Javascript 1 10-15-2006 08:41 PM
How do fix: "Wrong number of arguments" / "invalid propert assignment"/ "Invalid argument" Java Guy Java 1 10-15-2006 08:31 PM
how do u invoke Tag b's Tag Handler from within Tag a's tag Handler? shruds Java 1 01-27-2006 03:00 AM
MacOS/NeXTStep propert list parsing? Lars Kellogg-Stedman Python 1 09-09-2003 11:42 AM



Advertisments