herencia de objetos y cmd nested

Esta es probablemente una pregunta básica de OO: estoy intentando hacer un menú de consola nested con cmd que ha ido bien. También quiero que todas mis sub-consolas tengan acceso a los mismos objetos. Esto no ha ido bien.

Mi ejemplo simple:

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() 

Cuando corro esto me sale

 > >menu1 1>info AttributeError: SubConsole1 instance has no attribute 'obj1' 

Inténtalo de nuevo.

 > >menu2 2>info NameError: global name 'obj1' is not defined 

No estoy seguro de si las SubConsoles deberían ser subclases de MainConsole . También traté de anidar las SubConsoles dentro de MainConsole .

No necesita herencia múltiple, pero necesita dar obj1 y obj2 a los objetos heredados, excepto si le da algunos valores predeterminados a obj1 y 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

 sub1 = SubConsole1(object1, object2) 

EDITAR Bien, malinterpreté lo que estás haciendo.

Tiene razón, SubConsole1 y 2 no necesitan heredar de MainConsole. Pero deberían tener una referencia a la consola principal.

Algo como:

 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 

Luego, puede acceder a los objetos que desee accediendo a self.maincon.obj1 y self.maincon.obj2

La otra opción, y probablemente una mejor desde el punto de vista del diseño, es extraer todos los objetos a los que desea acceder en un objeto contenedor de contexto, y hacer que todos los diversos objetos Cmd mantengan su propia referencia a ese contenedor de contexto.

Algo como esto:

 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() 

Espero haber sido lo suficientemente claro.

La otra respuesta es correcta en la medida en que no debería utilizar la herencia múltiple, ya que lo siguiente es cierto:

 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 

También sería aconsejable crear un método de su clase principal que cree subcmds, pasando su referencia a la función __init__ del __init__ . De esta manera tienes tu objeto para engendrar a sus hijos de forma más natural.

 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 

Luego, puede acceder a los objetos que desee accediendo a self.maincon.obj1 y self.maincon.obj2 y obtener el sub-cmd ejecutando maincon.spawnsubconsole() asumiendo que maincon es una instancia de la clase de la consola principal.