Re: [Tutor] detecting data member changes

2007-04-24 Thread Alan Gauld
Luke Paireepinart [EMAIL PROTECTED] wrote

 class wiimote(object):
def __init__(self):
self.leds = [0,0,0,0]
def updateLEDs(self):
do_stuff()#write correct output report to wiimote to toggle 
 LEDs.

 So basically what I want to do is that whenever the self.leds 
 variable
 is changed, the updateLEDs method is called.

I'm not sure what your concern is here.
Since leds is an attribute of this class and therefore should only
be changed by a message to this class, then it should be easy
enough to ensure that each method that updates the leds calls
updateLED() when it makes a change

Or are you concerned about the possibility of someone directly
modifying leds from outside the class (naughty!). If its the latter
then you have the usual Python options:
- Make it single underscored and comment the fact that
  mods should call update:LED() - The pythonic way of consenting 
adults.
- Use the double underscore to make leds private
- Use setattr as you describe - I'm not clear why you need dictionary
  access though?
- Use a property to make direct access via a method
- Make leds a class which uses setattr...

Or am I missing something else?

 I know I could use a __setattr__ but then I'd have to access the 
 leds
 using a dictionary with an 'LED' key mapped to the status array.
 It's not necessarily a bad thing for my own use, but it seems like 
 it'd
 be off-putting to other people using my library.

Given that users of your class shouldn't be accessing leds directly
the format of the data should be of no interest to them. And a format
that discourages direct access would be a good thing - provided
your message interface makkes use of the class easy.

HTH,

-- 
Alan Gauld
Author of the Learn to Program web site
http://www.freenetpages.co.uk/hp/alan.gauld 


___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] detecting data member changes

2007-04-24 Thread Kent Johnson
Luke Paireepinart wrote:
 Supposing I have a class like this:
 
 class wiimote(object):
 def __init__(self):
 self.leds = [0,0,0,0]
 def updateLEDs(self):
 do_stuff()#write correct output report to wiimote to toggle LEDs.
 
 So basically what I want to do is that whenever the self.leds variable 
 is changed, the updateLEDs method is called.
 ( I can't call it constantly in a loop because 1) the wii remote freaks 
 out, and 2) that seems pretty ineffiicent.)

Make leds a property:

class wiimote(object):
 def __init__(self):
 self._leds = [0, 0, 0, 0]

 def _set_leds(self, leds):
 self._leds = leds
 self._updateLEDs()

 def _get_leds(self):
 return self._leds

 leds = property(_get_leds, _set_leds)

 def _updateLEDs(self):
 print self._leds

w = wiimote()
print w.leds
w.leds = [1, 2, 3, 4]
print w.leds

I renamed _updateLEDs because it doesn't seem like this should be part 
of the public interface.

If you don't like having _set_leds and _get_leds in the namespace of 
wiimote, use one of the recipes here:
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/205183
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/410698

 I know I could use a __setattr__ but then I'd have to access the leds 
 using a dictionary with an 'LED' key mapped to the status array.
 It's not necessarily a bad thing for my own use, but it seems like it'd 
 be off-putting to other people using my library.

I don't understand this part. It seems to me this would work:
def __setattr__(self, name, value):
   object.__setattr__(self, name, value)
   if name == 'leds':
 self._updateLEDs()

Kent
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] detecting data member changes

2007-04-24 Thread Luke Paireepinart


 Make leds a property:

 class wiimote(object):
 def __init__(self):
 self._leds = [0, 0, 0, 0]

 def _set_leds(self, leds):
 self._leds = leds
 self._updateLEDs()

 def _get_leds(self):
 return self._leds

 leds = property(_get_leds, _set_leds)

 def _updateLEDs(self):
 print self._leds

 w = wiimote()
 print w.leds
 w.leds = [1, 2, 3, 4]
 print w.leds
Wow, that's cool.  I need to read more about properties.

 I renamed _updateLEDs because it doesn't seem like this should be part 
 of the public interface.
Yeah, it was prepended with an underscore in my code, I forgot to put it 
when I simplified the code here.  *embarrassed*

 If you don't like having _set_leds and _get_leds in the namespace of 
 wiimote, use one of the recipes here:
 http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/205183
 http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/410698

 I know I could use a __setattr__ but then I'd have to access the leds 
 using a dictionary with an 'LED' key mapped to the status array.
 It's not necessarily a bad thing for my own use, but it seems like 
 it'd be off-putting to other people using my library.

 I don't understand this part. It seems to me this would work:
 def __setattr__(self, name, value):
   object.__setattr__(self, name, value)
   if name == 'leds':
 self._updateLEDs()
What I meant was that it'd require people to access the variable via
classinstance['leds']
instead of
classinstance.leds
which is what I was aiming for.
I apologize, I should've waited till the morning to e-mail so I could be 
more coherent.

Is this properties method acceptable Python form or is it more proper to 
have modifying member functions like Alan said?
Or is it really up to me on how I want to implement it?
Thanks,
-Luke

 Kent


___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] detecting data member changes

2007-04-24 Thread Kent Johnson
Luke Paireepinart wrote:

 I know I could use a __setattr__ but then I'd have to access the leds 
 using a dictionary with an 'LED' key mapped to the status array.
 It's not necessarily a bad thing for my own use, but it seems like 
 it'd be off-putting to other people using my library.

 I don't understand this part. It seems to me this would work:
 def __setattr__(self, name, value):
   object.__setattr__(self, name, value)
   if name == 'leds':
 self._updateLEDs()
 What I meant was that it'd require people to access the variable via
 classinstance['leds']
 instead of
 classinstance.leds
 which is what I was aiming for.
 I apologize, I should've waited till the morning to e-mail so I could be 
 more coherent.

No, the above code should work with classinstance.leds. Maybe you are 
confusing __setattr__ - which affects attributes like .leds - with 
__setitem__ which is used for classinstance['leds']

 
 Is this properties method acceptable Python form or is it more proper to 
 have modifying member functions like Alan said?

Alan and I don't always agree on questions like this. I don't take such 
a hard position about direct attribute access. IMO using a property is 
more Pythonic than making an explicit method. But I think one of the 
nice things about Python is you don't have to write explicit getters and 
setters; you can use plain attribute access to get at plain data, then 
if you need to add some behaviour just change the attribute to a property.

 Or is it really up to me on how I want to implement it?

Of course, it's your code, right?

Kent
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] detecting data member changes

2007-04-24 Thread Luke Paireepinart

 No, the above code should work with classinstance.leds. Maybe you are 
 confusing __setattr__ - which affects attributes like .leds - with 
 __setitem__ which is used for classinstance['leds']
Ah, yes. You hit the hail on the nead there, Kent.  Thanks for 
clarifying that for me.


 Is this properties method acceptable Python form or is it more proper 
 to have modifying member functions like Alan said?

 Alan and I don't always agree on questions like this. I don't take 
 such a hard position about direct attribute access. IMO using a 
 property is more Pythonic than making an explicit method. But I think 
 one of the nice things about Python is you don't have to write 
 explicit getters and setters; you can use plain attribute access to 
 get at plain data, then if you need to add some behaviour just change 
 the attribute to a property.
I can see how some people might be surprised to know that changing 
classinstance.leds automagically sends a communication packet to the wii 
remote without their knowledge, but if they're aware of the side-effect, 
it seems to be a more elegant way of doing things to me (with properties 
vs. an explicit method), at least in this case.

 Or is it really up to me on how I want to implement it?

 Of course, it's your code, right?
Yes, but it's code I plan on open-sourcing, so I'm trying to make it 
clear what's happening in case I get other developers to help in the future.

-Luke
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] detecting data member changes

2007-04-24 Thread Kent Johnson
Luke Paireepinart wrote:
 I can see how some people might be surprised to know that changing 
 classinstance.leds automagically sends a communication packet to the wii 
 remote without their knowledge, but if they're aware of the side-effect, 
 it seems to be a more elegant way of doing things to me (with properties 
 vs. an explicit method), at least in this case.

I think so.

 Or is it really up to me on how I want to implement it?

 Of course, it's your code, right?
 Yes, but it's code I plan on open-sourcing, so I'm trying to make it 
 clear what's happening in case I get other developers to help in the 
 future.

Using properties in this way is accepted practice.

Kent
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] detecting data member changes

2007-04-24 Thread Alan Gauld
Luke Paireepinart [EMAIL PROTECTED] wrote

 Is this properties method acceptable Python form or is it more 
 proper to
 have modifying member functions like Alan said?

Properties is fine and was one of the options that I suggested.

However I didn't mean you should have modifying member
functions in the sense of set/get merthods - I actually hate
those generally!

What I meant is that, whatever a wiimote is, it should be offering
up a behaviour oriented inteface that, as a side-effect, changes
the internal leds attribute. OOP is all about abstracting some
higher level object into a set of behaviours. The attributes of an
object should only really be there to support those higher
behaviours. So what is it that a wiimote does? And how
does that behaviour affect the leds? That is the set of methods
to build. (Since I've never heard of a wiimote I have no idea
what the abstract behaviour might be!)

For example, if I build a lamp object I might have an
_isLit boolean attribute internally.
Now I could write a method to set the _isLit attribute to
True or False

lamp = Lamp()
lamp.setIsLit(True)
lamp.setIsLit(False)

And superficioally it looks like OK code that does the job.

But that's not how people intuitively think of lamps.
They light them or turn them off. So the code is better if
the Lamp class provides on/off methods that control the
_isLit attribute:

lamp = Lamp()
lamp.on()
lamp.off()

And its easier to use so there no temptaiuon to mess with the
attribute directly and I can change the _isLit type from Boolean
to a number or a string or whatever I want and the client code
is unaffected.

Thats what I mean about providing a message interface that negates
the need for users of the class to know or care about the leds 
attribute.
If you make it intuitive and easy to use the class via messages then
there is no incentive to go messing with the internals.

However if you do need direct access to a data attribute then
direct access is usually OK. If the class is primarily there to
store some bit oif data (but that should be the exception in
OOP) then you might as well offer direct access as write
get/set methods But if you want to ensure some kind of
behaviour is associated with the attribute then use a property
or setattr().

 Or is it really up to me on how I want to implement it?

Ultimately, it's always up to the programmer how you
implement it! :-)

But some techniques make your life a bit easier is all.

-- 
Alan Gauld
Author of the Learn to Program web site
http://www.freenetpages.co.uk/hp/alan.gauld 


___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor