views:

14

answers:

3

Hi,

I am attempting to store a list of commands to send down a serial cable using deque in Python.

My function "send_command" accepts 3 values; The command, an int. pause and a boolean wait. its definition is as follows.

def send_command(self, command, pause=0, wait=False):

What I would like to do is, rather than calling this function like so:

send_command("A234", 5, True)

... or...

send_command("B4242")

I'd like to be able to store up commands inside a deque list and use the popleft function to then call my function. This would allow me to do things such as:

CommandList = deque((['A234', 5, True], ['B4242']))

...and use the deque.append() as a way to keep adding things to the list, which would then in turn be sent to my send_command function. I could then drop in and out of the list new commands when they are needed (or as quickly as the serial part of my code can do).

The part I'm struggling with is actually using the CommandList.popleft, or any part of the deque list as the args for my send_command function. It doesn't seem as straight forward as:

send_command(CommandList.popleft)

I'm sure it's something simple, but I cannot figure it out.

Can anyone help?

Thank-you kindly.

Andy

A: 

Have you tried:

send_command(CommandList.popleft()) # note the ()
MAK
Yes... didn't work either :(. I think its the def. of my function that's the trouble though.
Andy Barlow
@Andy Barlow: Sorry, I guess I didn't read the question carefully enough. @unbeli's answer seems more appropriate.
MAK
+2  A: 

probably you need something like:

obj.send_command(*CommandList.popleft())

That is, call popleft and use the result as an argument list for send_command. self argument suggests this is a member function, so you need to call it on an object

Another way, as I wrote in the comment, is to store prepared functions with something like this:

def make_command(obj, *args, **kwargs):
    def f():
        obj.send_command(*args, **kwargs)
    return f

Then you can do

queue.append(make_command(obj, 'ABC', whatever='else'))

and then execute:

command = queue.popleft()
command()
unbeli
Ahhha! What does seem to work is... self.send_command(*self.CommandList.popleft()) ... However, does that mean that I cannot call my function like this any more: send_command("A1234", wait=True) or is there a way of storing that inside the deque? self.CommandList.append(['b23456', wait=True]) doesn't work like it would normally. Any ideas?
Andy Barlow
yes you can. You can unpack argument lists as *arglist and dictionaries with keyword arguments with **argdict. However, there is no way to store it in one piece, like you wrote. It might be more convenient to store closures ready to be called instead.
unbeli
see update for an example
unbeli
A: 

unbeli is right - you need the () to call the function, and you need * to unpack the arguments. However, there's no need for using deque when you can just do this:

commandlist = [['A234', 5, True], ['B4242'], ['A234', 0]]

for command in commandlist:
   send_command(*command)

and that will work perfectly fine. For more info, see unpacking argument lists.

Queues are really only necessary if you're doing something in which you want to consume the values - say you want your commandlist to be empty when you're done. Of course you could also do the same thing with a list:

q = [1,2,3,4]
while q:
   print q.pop(0)
print q

HTH

Wayne Werner