2011-04-28 80 views
2

这可能是一个基本的OO问题: 我正在尝试使用cmd进行嵌套的控制台菜单,该菜单运行良好。 我也希望我的所有子控制台都可以访问相同的对象。这并没有好转。对象继承和嵌套cmd

我简单的例子:

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

当我运行此我得到

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

再试一次。

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

我不确定SubConsole是否应该是MainConsole的子类。我也尝试在MainConsole内嵌套SubConsoles。

+1

你不应该在这里使用多重继承。 – 2011-04-28 16:55:18

+0

增加了另一种做法,请查看。 – rossipedia 2011-04-28 17:21:17

+0

做任何这些答案有帮助吗?如果不是,请提供进一步澄清。 – theheadofabroom 2011-04-29 06:22:33

回答

2

您不需要多重继承,但需要将Obj1和obj2赋予继承的对象,除非将某些默认值赋予obj1和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 

通过实例化:

sub1 = SubConsole1(object1, object2) 
4

编辑好的,我误解了你在做什么。

你是对的,SubConsole1和2不需要从MainConsole继承。但他们有一个参考主控制台。

喜欢的东西:

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 

然后,您可以通过访问self.maincon.obj1self.maincon.obj2

另一种选择访问所需的对象,并可能从设计的角度来看一个更好的,就是拉将所有要访问的对象放入Context容器对象中,并让所有各种对象保持对该Context容器的引用。

事情是这样的:

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

希望我是很清晰。

+0

谢谢,我花了一分钟才弄清楚ConsoleContext,但现在我认为它是分享对象的好方法。我仍然不清楚一个对象的实例如何继承另一个对象实例的方法和属性(或者即使我的术语是正确的)。我希望我在学校上过一些CS课程。 – RyanN 2011-04-29 14:16:23

+0

这是维基百科关于继承的简单英文页面:http://simple.wikipedia.org/wiki/Inheritance_(computer_science)希望它有帮助 – rossipedia 2011-04-29 22:07:56

2

对方回答是正确的,只要你不应该使用多个inherritance,如符合下列条件:

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 

这也将是明智的创建一个主类的方法来创建子文件,并将它们的引用传递给子文件的函数__init__。这样你就可以让自己的物体更自然地产生它的孩子。

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 

然后,您可以通过访问self.maincon.obj1self.maincon.obj2获得想要的对象并获取子-CMD运行maincon.spawnsubconsole()假设maincon是主控制台类的一个实例。