Re: Move dictionary from instance to class level

2009-08-30 Thread Frank Millman

Anthony Tolle wrote:
> To take things one step further, I would recommend using decorators to
> allow symbolic association of functions with the message identifiers,
> as follows:
>

[...]

That's neat. Thanks.

Frank


-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Move dictionary from instance to class level

2009-08-30 Thread Frank Millman

"Frank Millman"  wrote:

Apologies for the triple-post.

I use google-groups for reading c.l.py, but I know that some people reject 
messages from there due to the volume of spam, so on the odd occasion when I 
want to send something I fire up Outlook Express and send it from there. It 
seems to be misbehaving today.

Sorry about that.

Frank


-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Move dictionary from instance to class level

2009-08-27 Thread Frank Millman
Dave Angel wrote:


> OK, that makes good sense.  And I withdraw any suggestion to use pickling, 
> since that could be subject to hacking.
>
> It now appears that the messages are only incidentally GUI events.  And 
> that you would be well advised to make every possible event a separate 
> message, so that if the server state and the client state get out of 
> synch, you can readily check and reject such operations.  For example, 
> you'd have a message for pressing the SUBMIT button on a particular form, 
> but you'd have different message types for other buttons on the same form, 
> or for SUBMIT on other forms.
>

I use the same message type for all SUBMITs, but the body of the message 
contains a unique id for each button.

When the server constructs the form, it assigns a unique id to each widget, 
and includes this id in the form definition it sends to the client. 
Therefore the server and client can unambiguously reference specific 
widgets, and there is no real danger of getting out of sync.

Frank




-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Move dictionary from instance to class level

2009-08-27 Thread Dave Angel

Frank Millman wrote:
Dave Angel wrote: 
  

Frank Millman wrote:


That is definitely *not* what I want to do.

I want to make the server as generic as possible, so that 
  

it can handle any

type of client, hopefully even including a browser 
  

eventually. Therefore the


server has no knowledge of wxPython event types.

I have abstracted all the event types I am interested in 
  

(the list is fairly

stable now). My protocol requires that the client maps a 
  

specific gui event

type to a message identifier, and the server maps the 
  

message identifier to


a method that handles the message.

Hope that makes sense.

Frank


  
  
Yes, it makes sense. Sorry for heading down that particular 
dead-end.  
But the more I think about it, the more likely I think it is 
that you'll 
be adding new message types, even if they're just variants of ones 
already defined.  So it might behoove you to have a shared "data 
structure" that describes the whole message, not just equates 
a name to 
an integer.


Or consider pickling.  I don't know the tradeoffs, but the 
idea is that 
an object is constructed at the other end that has all the same data 
members as the object you had at this end.  Perhaps with a flexible 
enough class definition, you could represent all or at least 
several of 
your messages with the same object.


I am curious about your topology.  You're sending events from 
the client 
(which presumably has a mouse and keyboard) to a server.  But 
what does 
the server do with those?  Does it have its own screen, or what?





I'll try to explain.

I am writing a fairly standard business/accounting application. (I am now
adding Business Process Management to it, which is complicating matters, but
that is another story.)

Most of the gui stuff is basic forms processing - screens with static data,
text fields for display and input of data, and buttons for signifying
certain actions to be taken.

My original attempt had both the gui and the business logic running on the
client, with a connection to a database running on a server. It worked, but
then I realised it was very insecure - it would be easy to hack the python
code, bypass the business logic, and allow any update to the database.

So my second attempt took all the business logic out of the client and put
it onto the server. To execute a form, the server builds a form definition
by creating objects to represent each of the widgets, creates a list of the
components with sufficient information for the client to render them , then
sends a json'd copy of the list to the client, which interprets it and
displays the required form. The client informs the server of each event, and
the server handles the event in much the same way as it did before when the
business logic was on the client.

For example, clicking a button triggers a response which could involve
updating the database, displaying another window with additional data, etc,
etc. Previously there would have been a method on the client designed to
handle the response, and the method would be added to the button constructor
so that it would be called when the button was clicked.

Now the method is on the server, and is stored as an attribute of the button
object on the server. When the user clicks the button, the message is passed
up to the server (each widget has its own id, which is part of the message),
the server is notified that the button was clicked, and it calls the
associated method.

There is a lot more to it than that, but hopefully that will give you an
idea.

If I ever get this to a workable state (it is taking far longer than I
anticipated) I will release it as open source, and will then welcome as much
feedback as possible.

Frank


  
OK, that makes good sense.  And I withdraw any suggestion to use 
pickling, since that could be subject to hacking.


It now appears that the messages are only incidentally GUI events.  And 
that you would be well advised to make every possible event a separate 
message, so that if the server state and the client state get out of 
synch, you can readily check and reject such operations.  For example, 
you'd have a message for pressing the SUBMIT button on a particular 
form, but you'd have different message types for other buttons on the 
same form, or for SUBMIT on other forms.


DaveA
--
http://mail.python.org/mailman/listinfo/python-list


Re: Move dictionary from instance to class level

2009-08-27 Thread Anthony Tolle
To take things one step further, I would recommend using decorators to
allow symbolic association of functions with the message identifiers,
as follows:

==

(MESSAGE_ONE
,MESSAGE_TWO
,MESSAGE_THREE
) = xrange(3)

class MyClass(object):
method_dict = {}

# create helper decorator
register_method = lambda msg, method_dict=method_dict: lambda
function: method_dict.setdefault(msg, function)

@register_method(MESSAGE_ONE)
def handle_one(self):
print 'handling MESSAGE_ONE'

@register_method(MESSAGE_TWO)
def handle_two(self):
print 'handling MESSAGE_TWO'

@register_method(MESSAGE_THREE)
def handle_three(self):
print 'handling MESSAGE_THREE'

# no longer need helper decorator
del register_method

# function to dispatch messages
def on_message_received(self, msg):
MyClass.method_dict[msg](self)

x = MyClass()

x.on_message_received(MESSAGE_ONE)
x.on_message_received(MESSAGE_TWO)
x.on_message_received(MESSAGE_THREE)

==

Note: the line containing the lambda definition is all one line.
-- 
http://mail.python.org/mailman/listinfo/python-list


RE: Move dictionary from instance to class level

2009-08-27 Thread Frank Millman
Dave Angel wrote: 
> 
> Frank Millman wrote:
> >
> > That is definitely *not* what I want to do.
> >
> > I want to make the server as generic as possible, so that 
> it can handle any
> > type of client, hopefully even including a browser 
> eventually. Therefore the
> > server has no knowledge of wxPython event types.
> >
> > I have abstracted all the event types I am interested in 
> (the list is fairly
> > stable now). My protocol requires that the client maps a 
> specific gui event
> > type to a message identifier, and the server maps the 
> message identifier to
> > a method that handles the message.
> >
> > Hope that makes sense.
> >
> > Frank
> >
> >
> >   
> Yes, it makes sense. Sorry for heading down that particular 
> dead-end.  
> But the more I think about it, the more likely I think it is 
> that you'll 
> be adding new message types, even if they're just variants of ones 
> already defined.  So it might behoove you to have a shared "data 
> structure" that describes the whole message, not just equates 
> a name to 
> an integer.
> 
> Or consider pickling.  I don't know the tradeoffs, but the 
> idea is that 
> an object is constructed at the other end that has all the same data 
> members as the object you had at this end.  Perhaps with a flexible 
> enough class definition, you could represent all or at least 
> several of 
> your messages with the same object.
> 
> I am curious about your topology.  You're sending events from 
> the client 
> (which presumably has a mouse and keyboard) to a server.  But 
> what does 
> the server do with those?  Does it have its own screen, or what?
> 

I'll try to explain.

I am writing a fairly standard business/accounting application. (I am now
adding Business Process Management to it, which is complicating matters, but
that is another story.)

Most of the gui stuff is basic forms processing - screens with static data,
text fields for display and input of data, and buttons for signifying
certain actions to be taken.

My original attempt had both the gui and the business logic running on the
client, with a connection to a database running on a server. It worked, but
then I realised it was very insecure - it would be easy to hack the python
code, bypass the business logic, and allow any update to the database.

So my second attempt took all the business logic out of the client and put
it onto the server. To execute a form, the server builds a form definition
by creating objects to represent each of the widgets, creates a list of the
components with sufficient information for the client to render them , then
sends a json'd copy of the list to the client, which interprets it and
displays the required form. The client informs the server of each event, and
the server handles the event in much the same way as it did before when the
business logic was on the client.

For example, clicking a button triggers a response which could involve
updating the database, displaying another window with additional data, etc,
etc. Previously there would have been a method on the client designed to
handle the response, and the method would be added to the button constructor
so that it would be called when the button was clicked.

Now the method is on the server, and is stored as an attribute of the button
object on the server. When the user clicks the button, the message is passed
up to the server (each widget has its own id, which is part of the message),
the server is notified that the button was clicked, and it calls the
associated method.

There is a lot more to it than that, but hopefully that will give you an
idea.

If I ever get this to a workable state (it is taking far longer than I
anticipated) I will release it as open source, and will then welcome as much
feedback as possible.

Frank

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Move dictionary from instance to class level

2009-08-27 Thread Dave Angel

Frank Millman wrote:

Dave Angel wrote:
  
Show me a sample client event handler, and maybe I can suggest how to 
encode it.  For example in wxPython, events are encoded  with 
an event 
object.  You could have the event send the object's type-string as an 
event ID.  No lookup at all.  And in fact, one event handler 
then might 
handle several of the events for a given widget, or even for multiple 
ones.  I guess it's not that simple, since you frequently 
have to pass 
other information, such as the state of the Ctrl-key, or the mouse 
position on the screen, which is not directly encoded in the 
event type.



That is definitely *not* what I want to do.

I want to make the server as generic as possible, so that it can handle any
type of client, hopefully even including a browser eventually. Therefore the
server has no knowledge of wxPython event types.

I have abstracted all the event types I am interested in (the list is fairly
stable now). My protocol requires that the client maps a specific gui event
type to a message identifier, and the server maps the message identifier to
a method that handles the message.

Hope that makes sense.

Frank


  
Yes, it makes sense. Sorry for heading down that particular dead-end.  
But the more I think about it, the more likely I think it is that you'll 
be adding new message types, even if they're just variants of ones 
already defined.  So it might behoove you to have a shared "data 
structure" that describes the whole message, not just equates a name to 
an integer.


Or consider pickling.  I don't know the tradeoffs, but the idea is that 
an object is constructed at the other end that has all the same data 
members as the object you had at this end.  Perhaps with a flexible 
enough class definition, you could represent all or at least several of 
your messages with the same object.


I am curious about your topology.  You're sending events from the client 
(which presumably has a mouse and keyboard) to a server.  But what does 
the server do with those?  Does it have its own screen, or what?



DaveA

--
http://mail.python.org/mailman/listinfo/python-list


RE: Move dictionary from instance to class level

2009-08-27 Thread Frank Millman
Dave Angel wrote:
> 
> Show me a sample client event handler, and maybe I can suggest how to 
> encode it.  For example in wxPython, events are encoded  with 
> an event 
> object.  You could have the event send the object's type-string as an 
> event ID.  No lookup at all.  And in fact, one event handler 
> then might 
> handle several of the events for a given widget, or even for multiple 
> ones.  I guess it's not that simple, since you frequently 
> have to pass 
> other information, such as the state of the Ctrl-key, or the mouse 
> position on the screen, which is not directly encoded in the 
> event type.

That is definitely *not* what I want to do.

I want to make the server as generic as possible, so that it can handle any
type of client, hopefully even including a browser eventually. Therefore the
server has no knowledge of wxPython event types.

I have abstracted all the event types I am interested in (the list is fairly
stable now). My protocol requires that the client maps a specific gui event
type to a message identifier, and the server maps the message identifier to
a method that handles the message.

Hope that makes sense.

Frank

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Move dictionary from instance to class level

2009-08-27 Thread Dave Angel

Frank Millman wrote:
Dave Angel wrote: 

  
Any time I see multiple lists like that which have to stay in 
synch, I think code-smell.





I don't think it is that bad, but I agree there is always room for
improvement.

  
Why not let the EVT's be passed as strings, and avoid the whole mapping 
to integers and mapping back detail?  And name the methods involved in a 
way that you can directly translate the string to the method name?





There is some merit in this. At present I am writing the server and the
client, and copy/paste the list of constants, so they are guaranteed to stay
in sync. (Maybe I should import it instead - even more fool-proof [the fool
being me, of course]).

However, it may happen that I want to open it up to 3rd-party clients in the
future, in which case I would have to publish some sort of API. It would
make more sense to identify the messages by a meaningful name rather than an
integer.

And yes, I could then use 'getattr' to retrieve the corresponding method on
the server side.

  
I've built such pairs of programs (not in Python), and studied the 
tradeoffs of various methods of coupling.  Cut & Paste is probably the 
worst way to do it.  Manual error is easy to creep in, where one copy is 
updated, and somebody neglects to update the other.  It's especially bad 
if the item order matters, as it does for enums and for your xlist() 
example.


Shared code works okay (have a module that both ends import).  But it 
assumes both ends are built and ship and install on a consistent basis.  
Not too hard when it's a single product on a single machine.  But if the 
two ends are on separate machines, especially separated by the Internet, 
you have to deal with version consistency problems.  If there's a time 
shift as well (file format), then you're stuck at that level.  Check the 
version, and either insist on exact match, or have a way to adapt to 
whichever end reports the earlier version.  Make no mistake, there will 
be new versions, and you'll have to deal with it.


Shared data is about the same, but can sometimes be more flexibly 
interpreted.  It also can have the advantage of being able to have 
multiple simultaneous versions on the same machine.  For the Internet 
case, picture a server that has to be able to serve several clients, 
each running different versions.  And it's tougher for corruption 
(accidental or malicious) to do serious damage.  I wouldn't want to do 
an import over the Internet live connection.


Best is if the necessary data is passed between the two ends during 
initialization, and both ends know how to make that data describe the 
protocol they'll use.  That can work as long as there's a notion of a 
session, and preferably if the session is two-way.  In the case of file 
formats, it means you have this data in the header of the file.


Sometimes for bandwidth reasons, you just want to transmit a version 
string, and not the entire table implied by that string.  Just realize 
the increased risks involved.


Probably the easiest way to stay in synch is if each message is 
self-describing.  To me that screams "text" for the id's.  It makes the 
message a bit larger, and you have to decide if it's worth it.  The 
overhead could very well be lost in the noise of packeting, in any 
tcp/ip protocol.


Note that all these have very gray boundaries.  And that underneath it 
all, it's all just data.
Barring that, make a single "structure" which lists the event 
names and 
method names in matched pairs, and derive whatever lists and 
dictionaries you actually need from that one structure.  And that 
structure should be shared between client and server code, 
perhaps as a 
text file that they both parse.  Or as a stream that's passed 
from one 
to the other during startup.  That way, consistency between 
them can be 
regulated (with version string in the file, for example)





I'm not sure how that would work. On the client side, I need to respond to a
'button-clicked' event from the gui system by sending an EVT_BUTTON_CLICKED
message to the server. In other words it is hard-coded into the client
program. I don't know how that would work if I read in a list of
message-types at startup.


  
Show me a sample client event handler, and maybe I can suggest how to 
encode it.  For example in wxPython, events are encoded  with an event 
object.  You could have the event send the object's type-string as an 
event ID.  No lookup at all.  And in fact, one event handler then might 
handle several of the events for a given widget, or even for multiple 
ones.  I guess it's not that simple, since you frequently have to pass 
other information, such as the state of the Ctrl-key, or the mouse 
position on the screen, which is not directly encoded in the event type.

DaveA




Thanks for the input - it is always good to have some fresh ideas.

Frank


  


--
http://mail.python.org/mailman/listinfo/python-list


RE: Move dictionary from instance to class level

2009-08-27 Thread Frank Millman
Dave Angel wrote: 

> Any time I see multiple lists like that which have to stay in 
> synch, I think code-smell.
> 

I don't think it is that bad, but I agree there is always room for
improvement.

> Why not let the EVT's be passed as strings, and avoid the whole mapping 
> to integers and mapping back detail?  And name the methods involved in a 
> way that you can directly translate the string to the method name?
> 

There is some merit in this. At present I am writing the server and the
client, and copy/paste the list of constants, so they are guaranteed to stay
in sync. (Maybe I should import it instead - even more fool-proof [the fool
being me, of course]).

However, it may happen that I want to open it up to 3rd-party clients in the
future, in which case I would have to publish some sort of API. It would
make more sense to identify the messages by a meaningful name rather than an
integer.

And yes, I could then use 'getattr' to retrieve the corresponding method on
the server side.

> Barring that, make a single "structure" which lists the event 
> names and 
> method names in matched pairs, and derive whatever lists and 
> dictionaries you actually need from that one structure.  And that 
> structure should be shared between client and server code, 
> perhaps as a 
> text file that they both parse.  Or as a stream that's passed 
> from one 
> to the other during startup.  That way, consistency between 
> them can be 
> regulated (with version string in the file, for example)
> 

I'm not sure how that would work. On the client side, I need to respond to a
'button-clicked' event from the gui system by sending an EVT_BUTTON_CLICKED
message to the server. In other words it is hard-coded into the client
program. I don't know how that would work if I read in a list of
message-types at startup.

> DaveA
> 

Thanks for the input - it is always good to have some fresh ideas.

Frank

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Move dictionary from instance to class level

2009-08-26 Thread Dave Angel

Frank Millman wrote:
"MRAB"  wrote in message 
news:mailman.444.1251290454.2854.python-l...@python.org...
  

An alternative is:



class MyClass(object):
  

... def on_message_received(self, msg):
... try:
... getattr(self, "method_%d" % msg)()
... except AttributeError:
... raise Exception("Unknown message")
... def method_0(self):
... print 'in method_0'
... def method_1(self):
... print 'in method_1'
...


my_obj = MyClass()
my_obj.on_message_received(0)
  

in method_0


my_obj.on_message_received(1)
  

in method_1


my_obj.on_message_received(2)
  

Traceback (most recent call last):
  File "", line 1, in 
  File "", line 6, in on_message_received
Exception: Unknown message



I like the idea. Unfortunately my real-world situation is a little more 
complex than my simple example implied.


This is a more typical example -

(EVT_GETLOGIN
,EVT_LOGOUT
,EVT_GETMENUOPT
,EVT_GOTFOCUS
,EVT_LOSTFOCUS
,EVT_BUTTONCLICKED
,EVT_CHECKBOX
...
) = xrange(28)

method_dict = {}
method_dict[EVT_GETLOGIN] = onGetLogin
method_dict[EVT_LOGOUT] = onLogout
method_dict[EVT_GETMENUOPT] = onGetMenuOpt
method_dict[EVT_GOTFOCUS] = onGotFocus
method_dict[EVT_LOSTFOCUS] = onLostFocus
method_dict[EVT_BUTTONCLICKED] = onButtonClicked
method_dict[EVT_CHECKBOX] = onCheckBox

You can probably figure out from my method names what I am doing here - the 
messages are sent by a thin client (wxPython), and processed by a server.I 
am anticipating some "don't do that" responses, but I like the concept, and 
so far it is very fast and responsive, so I will pursue it for now.


Thanks for the input.

Frank


  
Any time I see multiple lists like that which have to stay in synch, I 
think code-smell.


Why not let the EVT's be passed as strings, and avoid the whole mapping 
to integers and mapping back detail?  And name the methods involved in a 
way that you can directly translate the string to the method name?


Barring that, make a single "structure" which lists the event names and 
method names in matched pairs, and derive whatever lists and 
dictionaries you actually need from that one structure.  And that 
structure should be shared between client and server code, perhaps as a 
text file that they both parse.  Or as a stream that's passed from one 
to the other during startup.  That way, consistency between them can be 
regulated (with version string in the file, for example)


DaveA

--
http://mail.python.org/mailman/listinfo/python-list


Re: Move dictionary from instance to class level

2009-08-26 Thread Frank Millman

"MRAB"  wrote in message 
news:mailman.444.1251290454.2854.python-l...@python.org...
> An alternative is:
>
> >>> class MyClass(object):
> ... def on_message_received(self, msg):
> ... try:
> ... getattr(self, "method_%d" % msg)()
> ... except AttributeError:
> ... raise Exception("Unknown message")
> ... def method_0(self):
> ... print 'in method_0'
> ... def method_1(self):
> ... print 'in method_1'
> ...
> >>> my_obj = MyClass()
> >>> my_obj.on_message_received(0)
> in method_0
> >>> my_obj.on_message_received(1)
> in method_1
> >>> my_obj.on_message_received(2)
> Traceback (most recent call last):
>   File "", line 1, in 
>   File "", line 6, in on_message_received
> Exception: Unknown message

I like the idea. Unfortunately my real-world situation is a little more 
complex than my simple example implied.

This is a more typical example -

(EVT_GETLOGIN
,EVT_LOGOUT
,EVT_GETMENUOPT
,EVT_GOTFOCUS
,EVT_LOSTFOCUS
,EVT_BUTTONCLICKED
,EVT_CHECKBOX
...
) = xrange(28)

method_dict = {}
method_dict[EVT_GETLOGIN] = onGetLogin
method_dict[EVT_LOGOUT] = onLogout
method_dict[EVT_GETMENUOPT] = onGetMenuOpt
method_dict[EVT_GOTFOCUS] = onGotFocus
method_dict[EVT_LOSTFOCUS] = onLostFocus
method_dict[EVT_BUTTONCLICKED] = onButtonClicked
method_dict[EVT_CHECKBOX] = onCheckBox

You can probably figure out from my method names what I am doing here - the 
messages are sent by a thin client (wxPython), and processed by a server.I 
am anticipating some "don't do that" responses, but I like the concept, and 
so far it is very fast and responsive, so I will pursue it for now.

Thanks for the input.

Frank


-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Move dictionary from instance to class level

2009-08-26 Thread MRAB

Frank Millman wrote:

On Aug 26, 10:54 am, Chris Rebert  wrote:

On Wed, Aug 26, 2009 at 1:22 AM, Frank Millman wrote:

A

class MyClass(object):
def on_message_received(self, msg):
self.method_dict[msg](self)

def method_0(self):
print 'in method_0'

def method_1(self):
print 'in method_1'
method_dict

method_dict = {0: method_0, 1: method_1}
#note this comes *after* the methods in question have been defined



Thanks, Chris. This is much better.


Is there some reason you aren't using a list instead of a dict?
e.g. method_dict = [method_0, method_1, method_2, etc]

For that matter, why are you associating methods with integers in the
first place?



I actually use constants to define my messages, like this -

(MESSAGE_ONE
,MESSAGE_TWO
,MESSAGE_THREE
) = xrange(3)

I can then refer to the messages by their description, but internally it 
uses integers.



An alternative is:

>>> class MyClass(object):
... def on_message_received(self, msg):
... try:
... getattr(self, "method_%d" % msg)()
... except AttributeError:
... raise Exception("Unknown message")
... def method_0(self):
... print 'in method_0'
... def method_1(self):
... print 'in method_1'
...
>>> my_obj = MyClass()
>>> my_obj.on_message_received(0)
in method_0
>>> my_obj.on_message_received(1)
in method_1
>>> my_obj.on_message_received(2)
Traceback (most recent call last):
  File "", line 1, in 
  File "", line 6, in on_message_received
Exception: Unknown message
>>>
--
http://mail.python.org/mailman/listinfo/python-list


Re: Move dictionary from instance to class level

2009-08-26 Thread Frank Millman
On Aug 26, 10:54 am, Chris Rebert  wrote:
> On Wed, Aug 26, 2009 at 1:22 AM, Frank Millman wrote:
>
> A
>
> class MyClass(object):
> def on_message_received(self, msg):
> self.method_dict[msg](self)
>
> def method_0(self):
> print 'in method_0'
>
> def method_1(self):
> print 'in method_1'
> method_dict
>
> method_dict = {0: method_0, 1: method_1}
> #note this comes *after* the methods in question have been defined
>

Thanks, Chris. This is much better.

> Is there some reason you aren't using a list instead of a dict?
> e.g. method_dict = [method_0, method_1, method_2, etc]
>
> For that matter, why are you associating methods with integers in the
> first place?
>

I actually use constants to define my messages, like this -

(MESSAGE_ONE
,MESSAGE_TWO
,MESSAGE_THREE
) = xrange(3)

I can then refer to the messages by their description, but internally it
uses integers.

Frank



-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Move dictionary from instance to class level

2009-08-26 Thread Frank Millman
On Aug 26, 10:54 am, Chris Rebert  wrote:
> On Wed, Aug 26, 2009 at 1:22 AM, Frank Millman wrote:
>
> A
>
> class MyClass(object):
> def on_message_received(self, msg):
> self.method_dict[msg](self)
>
> def method_0(self):
> print 'in method_0'
>
> def method_1(self):
> print 'in method_1'
> method_dict
>
> method_dict = {0: method_0, 1: method_1}
> #note this comes *after* the methods in question have been defined
>

Thanks, Chris. This is much better.

> Is there some reason you aren't using a list instead of a dict?
> e.g. method_dict = [method_0, method_1, method_2, etc]
>
> For that matter, why are you associating methods with integers in the
> first place?
>

I actually use constants to define my messages, like this -

(MESSAGE_ONE
,MESSAGE_TWO
,MESSAGE_THREE
) = xrange(3)

I can then refer to the messages by their description, but internally it
uses integers.

Frank



-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Move dictionary from instance to class level

2009-08-26 Thread Frank Millman
On Aug 26, 10:54 am, Chris Rebert  wrote:
> On Wed, Aug 26, 2009 at 1:22 AM, Frank Millman wrote:
>
> A
>
> class MyClass(object):
> def on_message_received(self, msg):
> self.method_dict[msg](self)
>
> def method_0(self):
> print 'in method_0'
>
> def method_1(self):
> print 'in method_1'
> method_dict
>
> method_dict = {0: method_0, 1: method_1}
> #note this comes *after* the methods in question have been defined
>

Thanks, Chris. This is much better.

> Is there some reason you aren't using a list instead of a dict?
> e.g. method_dict = [method_0, method_1, method_2, etc]
>
> For that matter, why are you associating methods with integers in the
> first place?
>

I actually use constants to define my messages, like this -

(MESSAGE_ONE
,MESSAGE_TWO
,MESSAGE_THREE
) = xrange(3)

I can then refer to the messages by their description, but internally it 
uses integers.

Frank


-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Move dictionary from instance to class level

2009-08-26 Thread Chris Rebert
On Wed, Aug 26, 2009 at 1:22 AM, Frank Millman wrote:
> Hi all
>
> I have a class that uses a dictionary to map message numbers to methods.
>
> Here is a simple example -
>
>    class MyClass(object):
>        def __init__(self):
>            self.method_dict = {}
>            self.method_dict[0] = self.method_0
>            self.method_dict[1] = self.method_1
>
>        def on_message_received(self, msg):
>            self.method_dict[msg]()
>
>        def method_0(self):
>            print 'in method_0'
>
>        def method_1(self):
>            print 'in method_1'
>
> I have quite a few methods, so the dictionary is growing - up to 28 methods
> so far. To avoid
> having to recreate the dictionary every time I create an instance of the
> class, I tried to move it
> up to the class level. Unfortunately it does not work. This is what I
> tried -
>
>    class MyClass(object):
>        method_dict = {}
>        method_dict[0] = method_0  # this gives an error
>        method_dict[1] = method_1
>
>        def on_message_received(self, msg):
>            self.method_dict[msg]()
>
>        def method_0(self):
>            print 'in method_0'
>
>        def method_1(self):
>            print 'in method_1'
>
> As written above, I get the following error -
>    NameError: name 'method_0' is not defined
>
> If I try self.method_0, I get 'self' is not defined.

Right, because you're in the *class* body; there's no "current
instance" to be "self"; in fact, there's not even any class for there
to be instances of yet.

> If I try __class__.method_0, I get '__class__' is not defined.

Right, because the class isn't created until its body has finished executing

> If I try MyClass.method_0, I get 'MyClass' is not defined.

See previous note. The class name can't be bound to anything until the
class itself has been created.

> Is there any variation on this theme that will work?
>
> #
>
> Ok, I found a variation that seems to work.
>
> Is this the preferred way, or is there a better alternative?

A

class MyClass(object):
def on_message_received(self, msg):
self.method_dict[msg](self)

def method_0(self):
print 'in method_0'

def method_1(self):
print 'in method_1'
method_dict

method_dict = {0: method_0, 1: method_1}
#note this comes *after* the methods in question have been defined

Is there some reason you aren't using a list instead of a dict?
e.g. method_dict = [method_0, method_1, method_2, etc]

For that matter, why are you associating methods with integers in the
first place?

Cheers,
Chris
--
http://blog.rebertia.com
-- 
http://mail.python.org/mailman/listinfo/python-list


Move dictionary from instance to class level

2009-08-26 Thread Frank Millman
Hi all

I have a class that uses a dictionary to map message numbers to methods.

Here is a simple example -

class MyClass(object):
def __init__(self):
self.method_dict = {}
self.method_dict[0] = self.method_0
self.method_dict[1] = self.method_1

def on_message_received(self, msg):
self.method_dict[msg]()

def method_0(self):
print 'in method_0'

def method_1(self):
print 'in method_1'

I have quite a few methods, so the dictionary is growing - up to 28 methods 
so far. To avoid
having to recreate the dictionary every time I create an instance of the 
class, I tried to move it
up to the class level. Unfortunately it does not work. This is what I 
tried -

class MyClass(object):
method_dict = {}
method_dict[0] = method_0  # this gives an error
method_dict[1] = method_1

def on_message_received(self, msg):
self.method_dict[msg]()

def method_0(self):
print 'in method_0'

def method_1(self):
print 'in method_1'

As written above, I get the following error -
NameError: name 'method_0' is not defined

If I try self.method_0, I get 'self' is not defined.

If I try __class__.method_0, I get '__class__' is not defined.

If I try MyClass.method_0, I get 'MyClass' is not defined.

Is there any variation on this theme that will work?

#

Ok, I found a variation that seems to work.

Is this the preferred way, or is there a better alternative?

class MyClass(object):

def on_message_received(self, msg):
#self.method_dict[msg]()  # had to change this to get it to work
self.method_dict[msg](self)

def method_0(self):
print 'in method_0'

def method_1(self):
print 'in method_1'

MyClass.method_dict = {}
MyClass.method_dict[0] = MyClass.method_0
MyClass.method_dict[1] = MyClass.method_1

As you can see, I had to add 'self' to the method arguments when calling the 
method.

Any comments?

Thanks

Frank Millman


-- 
http://mail.python.org/mailman/listinfo/python-list