Can I make these getters/setters?

  • Thread starter Michael George Lerner
  • Start date
M

Michael George Lerner

Hi,

As part of my GUI, I have lots of fields that people can fill in,
defined like this:

self.selection = Pmw.EntryField(group.interior(),
labelpos='w',
label_text='Selection to use:
',
value='(polymer)',
)

I then use self.selection.get_value() and self.selection.set_value(),
and those two functions are the only ways in which I care about
self.selection. I've never really used properties, getters or setters
before. I tried this, but it didn't work:

def __init__(self):
self._selection = Pmw.EntryField(group.interior(),
labelpos='w',
label_text='Selection to use:
',
value='(polymer)',
)
self.selection = property(self._selection.get_value
(),self._selection.set_value())

Of course, I really have ~40 things that I'd like to do this for, not
just one, so I'd like to find a fairly concise syntax.

In case it helps, here's a complete example of me failing. I'd like it
to print out "2" instead of "<property object at 0xe763f0>"

class Foo(object):
def __init__(self,val):
self._val = val
def get(self):
return self._val
def set(self,val):
self._val = val
class Bar(object):
def __init__(self):
self._v = Foo(2)
self.v = property(self._v.get,self._v.set)
b = Bar()
print b.v
 
S

Steven D'Aprano

I then use self.selection.get_value() and self.selection.set_value(),
and those two functions are the only ways in which I care about
self.selection. I've never really used properties, getters or setters
before. I tried this, but it didn't work:

def __init__(self):
self._selection = Pmw.EntryField(group.interior(),
labelpos='w',
label_text='Selection to use:
',
value='(polymer)',
)
self.selection = property(self._selection.get_value
(),self._selection.set_value())


property() only works if the property is defined in the *class*, not the
instance. In other words, this will work:

class K(object):
def _parrot_getter(self):
return "Norwegian %s" % self._colour
parrot = property(_parrot_getter)
def __init__(self, colour="Blue"):
self._colour = colour

But this will not:

class K(object):
def _parrot_getter(self):
return "Norwegian %s" % self._colour
def __init__(self, colour="Blue"):
self._colour = colour
parrot = property(_parrot_getter)
 
B

Bruno Desthuilliers

Michael George Lerner a écrit :
Hi,

As part of my GUI, I have lots of fields that people can fill in,
defined like this:

self.selection = Pmw.EntryField(group.interior(),
labelpos='w',
label_text='Selection to use:
',
value='(polymer)',
)

I then use self.selection.get_value() and self.selection.set_value(),
and those two functions are the only ways in which I care about
self.selection. I've never really used properties, getters or setters
before. I tried this, but it didn't work:

def __init__(self):
self._selection = Pmw.EntryField(group.interior(),
labelpos='w',
label_text='Selection to use:
',
value='(polymer)',
)
self.selection = property(self._selection.get_value
(),self._selection.set_value())

What you're passing here are the results of the calls to .get_value and
..set_value, not the methods themselves. You'd want:

self.selection = property(
self._selection.get_value,
self._selection.set_value
)

But as Steven already mentioned, property only works as a class
attribute, not as an instance attribute. What you need here is:

class Parrot(object):
def __init__(self):
self._selection = Pmw.EntryField(...)


selection = property(
lambda self: self._selection.get_value(),
lambda self, value: self._selection.set_value(value)
)

Of course, I really have ~40 things that I'd like to do this for, not
just one, so I'd like to find a fairly concise syntax.


the property object is just one possible application of the descriptor
protocol. You could write your own custom descriptor (warning: untested
code, may contains typos etc):

class FieldProperty(object):
def __init__(self, fieldname):
self._fieldname = fieldname

def __get__(self, instance, cls):
if instance is None:
# can't work on the class itself
return self
return getattr(instance, self._fieldname).get_value()

def __set__(self, instance, value):
getattr(instance, self._fieldname).set_value(value)


class Parrot(object):
def __init__(self):
self._selection = Pmw.EntryField(...)


selection = FieldProperty("_selection")



HTH
 
M

Michael \rotini\ Lerner

Excellent. I now understand why it was broken, and a slightly tweaked
version of FieldProperty does what I want. Thanks!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,763
Messages
2,569,563
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top