Използване на Deque.popleft като аргументи за функция

Опитвам се да съхраня списък с команди за изпращане на сериен кабел с помощта на deque в Python.

Моята функция "send_command" приема 3 стойности; Командата, int. пауза и булево изчакване. неговата дефиниция е следната.

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

Това, което бих искал да направя, е вместо да извиквам тази функция така:

send_command("A234", 5, True)

... or...

send_command("B4242")

Бих искал да мога да съхранявам команди в списък с deque и да използвам функцията popleft, за да извикам след това моята функция. Това би ми позволило да правя неща като:

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

... и използвайте deque.append() като начин да продължите да добавяте неща към списъка, които след това ще бъдат изпратени на моята функция send_command. След това бих могъл да въвеждам и излизам от списъка с нови команди, когато са необходими (или толкова бързо, колкото може да направи серийната част на моя код).

Частта, с която се боря, всъщност е използването на CommandList.popleft или която и да е част от списъка с deque като аргументи за моята функция send_command. Не изглежда толкова ясно като:

send_command(CommandList.popleft)

Сигурен съм, че е нещо просто, но не мога да го разбера.

Може ли някой да помогне?

Любезно ви благодаря.

Анди


person Schodemeiss    schedule 14.07.2010    source източник


Отговори (3)


вероятно имате нужда от нещо като:

obj.send_command(*CommandList.popleft())

Тоест, извикайте popleft и използвайте резултата като списък с аргументи за send_command. Аргументът self подсказва, че това е членска функция, така че трябва да я извикате на обект

Друг начин, както написах в коментара, е да съхранявате подготвени функции с нещо подобно:

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

Тогава можете да направите

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

и след това изпълнете:

command = queue.popleft()
command()
person unbeli    schedule 14.07.2010
comment
Ахаха! Това, което изглежда работи е... self.send_command(*self.CommandList.popleft()) ... Това обаче означава ли, че вече не мога да извиквам функцията си по този начин: send_command(A1234, wait=True) или има ли начин това да се съхрани в deque? self.CommandList.append(['b23456', wait=True]) не работи както обикновено. Някакви идеи? - person Schodemeiss; 15.07.2010
comment
да, можеш. Можете да разопаковате списъци с аргументи като *arglist и речници с ключови аргументи с **argdict. Обаче няма как да се съхрани цяла, както си написал. Вместо това може да е по-удобно да съхранявате затваряния, готови за извикване. - person unbeli; 15.07.2010

unbeli е прав - имате нужда от (), за да извикате функцията, и имате нужда от *, за да разопаковате аргументите. Въпреки това, няма нужда да използвате deque, когато можете просто да направите това:

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

for command in commandlist:
   send_command(*command)

и това ще работи перфектно. За повече информация вижте разопаковане на списъци с аргументи.

Опашките наистина са необходими само ако правите нещо, в което искате да консумирате стойностите - да кажем, че искате списъкът ви с команди да е празен, когато сте готови. Разбира се, можете да направите същото и със списък:

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

HTH

person Wayne Werner    schedule 14.07.2010

Опитвали ли сте:

send_command(CommandList.popleft()) # note the ()
person MAK    schedule 14.07.2010
comment
Да... също не проработи :(. Мисля, че проблемът е в дефиницията на моята функция. - person Schodemeiss; 15.07.2010
comment
@Andy Barlow: Съжалявам, предполагам, че не прочетох въпроса достатъчно внимателно. Отговорът на @unbeli изглежда по-подходящ. - person MAK; 15.07.2010