dman
dman

Reputation: 11064

Python Class Inheritance Function and Pass Parameters From Child

class BaseMenu(object):
    def display(self):
        header = "FooBar YO"
        term = getTerminalSize()
        #sys.stdout.write("\x1b[2J\x1b[H")
        print header.center(term, '*')
        #print sub_menu.center(term, '+')
        print "Please choose which option:"
        for i in options:
            print(
                str(options.index(i)+1) + ") "
            )

class Servers(BaseMenu):
    def __init__(self):
        #super(Servers, self).__init__("server")
        pass

    def list_foo(self):
        pass
    def list_bar(self):
        pass
    options = (
        list_foo,
        list_bar
        )

Trying to make a series of text menus starting with Main Menu -> Servers sub menu. When Servers() inherits display() from BaseClass, how can I make the inherited function display() receive options tuple and sub_menu = "Server Menu" string that are contained in Servers() class?

Upvotes: 2

Views: 5650

Answers (2)

Ryan Haining
Ryan Haining

Reputation: 36792

You can use self.options and self.sub_menu in the display function, but why are you referencing them at all in the BaseMenu class which knows nothing about options or sub_menu?

A second issue, you're passing the "server" argument to a class whose __init__ takes no arguments so you'll need to add that.

If you are intending to never instantiate a BaseMenu object, then it is an Abstract Base Class (or ABC). You can define it as such using pythons abc module to make sure the inheriting class defines the properties you are expecting:

import abc

class BaseMenu(object):
    __metaclass__ = abc.ABCMeta  #indicate that this is an ABC

    @abc.abstractproperty  # prevent derived classes that don't have options
    def options(self):
        pass

    @abc.abstractproperty
    def sub_menu(self):
        pass

    def __init__(self, menu_name): # takes the menu name as an argument ("server")
        self.menu_name = menu_name

    def display(self):
        header = "FooBar YO"
        term = getTerminalSize()
        print header.center(term, '*')
        print self.sub_menu.center(term, '+') # NOTE self.sub_menu
        print "Please choose which option:"
        for i in self.options: # NOTE self.options
            print(self.options.index(i)+1 + ") ")

If any class tries to inherit from BaseMenu without defining options and sub_menu it will result in a TypeError like the following upon instantiation:

TypeError: Can't instantiate abstract class Servers with abstract methods options

Upvotes: 4

Gauthier Boaglio
Gauthier Boaglio

Reputation: 10242

I'm not sure that I get completly what you are asking here, so tell me, what about this ?

class BaseMenu(object):

    # Added some attributes here:
    menuName = ""
    options = ()

    def __init__(self, menu_name, opt):
        self.menuName = menu_name  # = "Servers Menu" when instantiated as Server
        self.options = opt         # the passed when instantiated as Server

    def display(self):

        # Use self.menuName and self.options here

        #...
        for i in self.options:
            print(
                str(self.options.index(i)+1) + ") " + str(i)
            )

class Servers(BaseMenu):

    def list_foo(self):
        pass
    def list_bar(self):
        pass

    options = (
        list_foo,
        list_bar
        )

    def __init__(self, menu_name):
        super(Servers, self).__init__(menu_name, self.options) 

Instantiate Servers class like this:

servers = Servers("Servers Menu")
servers.display()

Outputs:

1) <function list_foo at 0x29e06e0>
2) <function list_bar at 0x29e0758>

Would it fit ?

Upvotes: 2

Related Questions