菜单 Class 使用非实例化菜单中的菜单选项

Menu Class uses menu option from non - instantiated menus

我正在尝试为我的 python CLI 应用程序创建菜单 class。当用户选择一个选项时,将触发相应的功能。

from collections import namedtuple

Option = namedtuple('Option', ['label', 'callback'])
class Menu:

    SEPARATOR = '-'

    _title = ''
    _options = []

    def __init__(self, title, options):
        self._title = title

        for option in options:
            self._options.append(Option(option[0], option[1]))

    def header(self, text):
        line = self.SEPARATOR * (len(text) + 2)
        return f"{line}\n {text}\n{line}\n"

    def display(self):
        string = self.header(self._title)

        for i, option in enumerate(self._options):
            string += f"{i + 1} {option.label}\n"

        return string

    def callback(self, i):
        if i <= len(self._options):
            return self._options[i - 1].callback

    def getInput(self):
        incorrect = True
        while incorrect:
            option = int(input('>> '))
            if option < 1 or option > len(self._options):
                print("Invalid Input")
            else:
                incorrect = False
        return self.options[option-1].callback()

我的第一个菜单:

mainMenu = Menu.Menu(
        "Main Menu - Please Select an Option", [
        ('Setup Attacker', setupAttacker),
        ('Setup Victim', setupVictim),
        ('Run Attack Simulation', runAttackSim),
        ('View Results', viewResults),
        ('Exit', quitProgram)])

在我制作第二个菜单之前一切都很顺利。

setupVictimMenu = Menu.Menu(
    "Setup Victim - Please Select an Option", [
    ('Download Server Software', installServerSoftware),
    ('Open a Port...', openPort),
    ('Send Malicious File', sendMaliciousFile)])

在 运行 程序上它给了我这个输出:

-------------------------------------
 Main Menu - Please Select an Option
-------------------------------------
1 Download Server Software
2 Open a Port...
3 Send Malicious File
4 Setup Attacker
5 Setup Victim
6 Run Attack Simulation
7 View Results
8 Exit

两个菜单选项合并了!我认为这个问题与 Class 菜单中的选项变量有关。两个列表都被它拿走了。

请注意,第二个列表是第一个列表的子菜单,所以我不明白为什么在调用第一个菜单时未实例化子菜单的情况下,为什么将选项组合在一起。

_options 变量是一个 class 变量。它在 Menu class.
实例之间共享 将其设为实例变量以使其对实例私有。

class Menu:

    SEPARATOR = "-"

    _title = ""
    # _options = []

    def __init__(self, title, options):
        self._title = title
        self._options = [Option(*option) for option in options]