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 objects. This has not gone well.
My simple Example:
import cmd
class MainConsole(cmd.Cmd):
def __init__(self,obj1,obj2):
cmd.Cmd.__init__(self)
self.prompt = ">"
self.obj1 = obj1 # The objects I want access to in all my consoles.
self.obj2 = obj2
self.menu1 = SubConsole1() # I could pass in the objects here as arguments
self.menu2 = SubConsole2() # but there should be a better way.
def do_menu1(self,args):
self.menu1.cmdloop()
def do_menu2(self,args):
self.menu2.cmdloop()
def do_info(self,args):
self.menu1.do_info(args)
self.menu2.do_info(args)
def do_exit(self,args):
return -1
class SubConsole1(cmd.Cmd,MainConsole):
def __init__(self):
cmd.Cmd.__init__(self)
self.prompt = "1>"
def do_action(self,args):
print self.obj1.someattr1 # Doesn't work
class SubConsole2(cmd.Cmd,MainConsole):
def __init__(self):
cmd.Cmd.__init__(self)
self.prompt = "2>"
def do_action(self,args):
print obj1.someattr2 # Doesn't work
class anobject(object):
def __init__(self,init_value):
self.someattr1 = init_value
self.someattr2 = init_value * 2
object1 = anobject(1)
object2 = anobject(2)
c=MainConsole(object1,object2)
c.cmdloop()
When I run this I get
>
>menu1
1>info
AttributeError: SubConsole1 instance has no attribute 'obj1'
Try again.
>
>menu2
2>info
NameError: global name 'obj1' is not defined
I'm not sure if the SubConsoles should be sub-classes of MainConsole
. I also tried nesting the SubConsoles inside of MainConsole
.
The other answer is correct insofar as you should not be using multiple inherritance, as the following is 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.Then you can access the objects you want by accessing
self.maincon.obj1
andself.maincon.obj2
and get the sub-cmd by runningmaincon.spawnsubconsole()
assuming maincon is an instance of the main console class.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.
instanciated by :
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:
Then you can access the objects you want by accessing
self.maincon.obj1
andself.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:
Hope I was clear enough.