object inheritance and nested cmd

后端 未结 3 1367
深忆病人
深忆病人 2021-01-07 01:11

This is probably a basic OO question: I\'m trying to do a nested console menu with cmd which has gone well. I also want all my sub-consoles to have access to the same object

相关标签:
3条回答
  • 2021-01-07 01:26

    You don't need multiple inheritance, but you need to give obj1 and obj2 to the inherited objects, except if you give some default values to obj1 and obj2.

    class SubConsole1(MainConsole):
        def __init__(self, obb1, obj2):
            MainConsole.__init__(self, obj1, obj2)
            self.prompt = "1>"
        def do_action(self,args):
            print self.obj1.someattr1 # Doesn't work
    

    instanciated by :

    sub1 = SubConsole1(object1, object2)
    
    0 讨论(0)
  • 2021-01-07 01:36

    The other answer is correct insofar as you should not be using multiple inherritance, as the following is true:

    class A(object):
      pass
    class B(A):
      pass
    class C(A):
      pass
    class D(B):
      pass
    a = A()
    b = B()
    c = C()
    d = D()
    
    isTrue = isinstance(a,A) and isinstance(b,A) and isinstance(c,A) and isinstance(d,A)
    isTrue = isTrue and isinstance(b,B)and isinstance(d,B)
    isTrue = isTrue and isinstance(c,C) 
    isTrue = isTrue and isinstance(d,D)
    
    >>> print isTrue
    True
    

    It would also be wise to create a method of your main class wich creates subcmds, passing their reference to the subcmd's __init__ function. This way you have your object spawn its children more naturally.

    class MainConsole(cmd.Cmd):
        def spawnsubconsole(self):
            return SubConsole1(self)
        def __init__(self):
           cmd.Cmd.__init__(self, obj1, obj2)
           self.obj1 = obj2
           self.obj2 = obj2
    
    class SubConsole1(cmd.Cmd):
        def __init__(self, maincon):
            cmd.Cmd.__init__(self)
            self.maincon = maincon
    

    Then you can access the objects you want by accessing self.maincon.obj1 and self.maincon.obj2 and get the sub-cmd by running maincon.spawnsubconsole() assuming maincon is an instance of the main console class.

    0 讨论(0)
  • 2021-01-07 01:41

    EDIT Okay, I misunderstood what you're doing.

    You are right, SubConsole1 and 2 do not need to inherit from MainConsole. But they should have a reference to the main console.

    Something like:

    class MainConsole(cmd.Cmd):
        def __init__(self):
           cmd.Cmd.__init__(self, obj1, obj2)
           self.obj1 = obj2
           self.obj2 = obj2
    
    class SubConsole1(cmd.Cmd):
        def __init__(self, maincon):
            cmd.Cmd.__init__(self)
            self.maincon = maincon
    

    Then you can access the objects you want by accessing self.maincon.obj1 and self.maincon.obj2

    The other option, and probably a better one from a design point of view, is to pull out all the objects you want to access into a Context container object, and have all the various Cmd objects maintain their own reference to that Context container.

    Something like this:

    import cmd
    from collections import namedtuple
    
    class MyConsole(cmd.Cmd):
        def __init__(self, context):
            cmd.Cmd.__init__(self)
            self.context = context
    
    class ConsoleContext(object):
        def __init__(self, **kwargs):
            self.__dict__ = kwargs
    
    class MainConsole(MyConsole):
        def __init__(self, context):
            MyConsole.__init__(self, context)
            self.menu1 = SubConsole1(context)
            self.menu2 = SubConsole2(context)
            self.prompt = '>'
    
        def do_menu1(self, args):
            self.menu1.cmdloop()
    
        def do_menu2(self, args):
            self.menu2.cmdloop()
    
        def do_quit(self, args):
            return True
    
    
    class SubConsole1(MyConsole):
        def __init__(self, context):
            MyConsole.__init__(self, context)
            self.prompt = '1>'
    
        def do_action(self, args):
            print self.context.message1
    
        def do_quit(self, args):
            return True
    
    
    class SubConsole2(MyConsole):
        def __init__(self, context):
            MyConsole.__init__(self, context)
            self.prompt = '2>'
    
        def do_action(self, args):
            print self.context.message2
    
        def do_quit(self, args):
            return True
    
    if __name__ == '__main__':
        context = ConsoleContext(message1='Message 1', message2='Message 2')
        con = MainConsole(context)
        con.cmdloop()
    

    Hope I was clear enough.

    0 讨论(0)
提交回复
热议问题