首页 > 解决方案 > 如何使用 LifoQueue 进行函数调用?

问题描述

我正在制作一个数独求解器,并希望以 LIFO 结构一次执行一个指令,以类似于大多数(或至少我)玩数独的方式。

我的求解器类的相关部分 -

class SudokuSolver():
    possible_answers = None

    def __init__(self, board):
        self.board = board
        self.instruction_stack = LifoQueue()
        ...

    def work_on_group(self, group_num):
        print(f"working on group {group_num}")
    
    def work_on_row(self, row):
        print(f"working on row {row}")

    def work_on_column(self, column):
        print(f"working on column {column}")
    
    def do_next_step(self):
        if self.instruction_stack.empty():
            self.instruction_stack.put(self.work_on_group(9))
            self.instruction_stack.put(self.work_on_group(8))
            ...
            self.instruction_stack.put(self.work_on_group(2))
            self.instruction_stack.put(self.work_on_group(1))
        self.instruction_stack.pop()

最终 my work_on_group,work_on_rowwork_on_column函数将具有标准,这些标准将随着结果的展开向堆栈添加指令。但是,现在,当我尝试时,我得到do_next_step()的是

working on group 9
working on group 8
...
working on group 2
working on group 1

因此,当我将它们放入堆栈而不是等待我弹出它们时,似乎我的函数正在评估。

理想情况下,当它正确运行时我会看到的只是

working on group 1

因为这是给出的最后一条指令,而我只有一个 pop 命令。

另一件值得注意的事情 - 这三个函数只需要一个参数,我可以看到基于需要更多参数的板的更复杂的函数,并且希望我的堆栈/弹出能够处理它 - 存储函数引用和然后使用任意数量的*args **kwargs. 我怎样才能做到这一点?

编辑:

我想出了这个可行的方法,我认为可以使用任意数量的位置参数,但不知道如何将关键字参数与它结合起来。

    def do_next_step(self):
        if self.instruction_stack.empty():
            self.instruction_stack.put((self.work_on_group,(9)))
            self.instruction_stack.put((self.work_on_group,(8)))
            self.instruction_stack.put((self.work_on_group,(7)))
            self.instruction_stack.put((self.work_on_group,(6)))
            self.instruction_stack.put((self.work_on_group,(5)))
            self.instruction_stack.put((self.work_on_group,(4)))
            self.instruction_stack.put((self.work_on_group,(3)))
            self.instruction_stack.put((self.work_on_group,(2)))
            self.instruction_stack.put((self.work_on_group,(1)))
        func, params = self.instruction_stack.get()
        func(params)

标签: pythonstackpython-3.6

解决方案


我通过将我的do_next_step功能更改为以下来完成这项工作

    def do_next_step(self):
        """
        Creates, and then does, next step into stack.
        """
        if self.instruction_stack.empty():
            self.instruction_stack.put((self.work_on_group,(9,),{}))
            self.instruction_stack.put((self.work_on_group,(8,),{}))
            self.instruction_stack.put((self.work_on_group,(7,),{}))
            self.instruction_stack.put((self.work_on_group,(6,),{}))
            self.instruction_stack.put((self.work_on_group,(5,),{}))
            self.instruction_stack.put((self.work_on_group,(4,),{}))
            self.instruction_stack.put((self.work_on_group,(3,),{}))
            self.instruction_stack.put((self.work_on_group,(2,),{}))
            self.instruction_stack.put((self.work_on_group,(1,),{}))
        func, params, keyword_params = self.instruction_stack.get()
        func(*params, **keyword_params)

推荐阅读