对象继承和嵌套cmd

发布于 2024-11-03 21:49:46 字数 1735 浏览 0 评论 0原文

这可能是一个基本的面向对象问题: 我正在尝试使用 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 的子类。我还尝试将 SubConsole 嵌套在 MainConsole 中。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

花海 2024-11-10 21:49:46

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

你是对的,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.obj1 和 self.maincon.obj2 来访问您想要的对象

另一种选择,可能是设计中更好的选择从角度来看,就是将要访问的所有对象拉出到 Context 容器对象中,并让所有各种 Cmd 对象维护自己对该 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()

希望我说得足够清楚。

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.

变身佩奇 2024-11-10 21:49:46

您不需要多重继承,但需要将 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)

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)
亣腦蒛氧 2024-11-10 21:49:46

另一个答案是正确的,因为您不应该使用多重继承,因为以下情况是正确的:

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.obj1 和 self.maincon.obj2 来访问你想要的对象,并通过运行 maincon.spawnsubconsole( ) 假设 maincon 是主控制台类的实例。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文