'How to efficiently make a text-based menu?

I am currently making a program with a text based menu, and I was wondering if there was anyway to avoid an excessive amount of if-statements while keeping it object oriented. I thought of something like this:

class Options:
    def displayOptions():
        #display user options
    def option1():
        #do option 1
    def option2():
        #do option 2 
    def option3():
        #do option 3 and so on

class Menu(Options):
    options = {1: option1(), 2: option2(), 3: option3()} #and so on 
    def promptUser():
        #prompts user to make a choice
    def printHeader():
        #prints header
    def handleInput():
        #checks if input is valid
    def begin():
        #initialize menu

Would something like this be convoluted? Is the Options class pointless? I'm pretty new to OOP and I was wondering how this would most efficiently be done.



Solution 1:[1]

This is a bit hacky but it gets the job done.

class Options:
    def doOption(self, opt):
        option = f'option{opt}'
        func = type(self).__dict__.get(option)
        if hasattr(func, '__call__'):
            return func(self)

        raise ValueError(f'Unsupported option: {opt}')

class Menu(Options):
    def option1(self):
        print('Foo!')

    def option2(self):
        print('Bar!')

    def optionbang(self):
        print('Bang!')

menu = Menu()
menu.doOption(1) # Foo!
menu.doOption(2) # Bar!
menu.doOption('bang') # Bang!

What this does is look through the the class' properties and try to find a function (i.e., hasattr(func, '__call__')) with the right name. The nice thing is that the logic doesn't even require opt to be an integer.

That being said, if this is your only use case, then I agree with @GradyPlayer in the comments that the abstraction probably isn't worth it.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1