许多类与许多对象

时间:2012-10-16 13:02:11

标签: python class object creation

我正在开发一个Python项目,我必须在我的代码中表示一个GUI结构。 它看起来像这样:

  • window1(包含button1,button2,button3,dialog1,...)
  • window2(包含button4,button5,dialog2,list1,...)

因此,有许多窗口,每个窗口都有不同的内容,并且不同的元素背后有不同的功能。每个窗口都可以有不同的自定义方法,只能在那里工作。

现在我有两种可能性:

第一个:

class Window1(object):
    def __init__(self):
        self.elements = {"button1":button1,"button2":button2,...}

    def customMethod(self):
        print "do custom"

class Window2(object):
    def __init__(self):
        self.elements = {"button4":button4,"button5":button5,...}

    def otherCustomMethod(self):
        print "do other custom"

...
window1 = Window1()
window2 = Window2()

但是如果我这样做,会有很多类,每个窗口一个,我只需要每个窗口的一个实例。 因此,第二种可能性是即时创建正确的对象:

# create template class
class WindowGeneric(object):
    pass

# create first window
window1 = WindowGeneric()
window1.elements = {"button4":button4,"button5":button5,...}

def customMethod(self):
    print "do custom"

window1.customMethod = customMethod.__get__(window1, WindowGeneric) #bind to instance

#create second window
window2 = WindowGeneric()
window2.elements = {"button4":button4,"button5":button5,...}

def otherCustomMethod(self):
    print "do other custom"

window1.otherCustomMethod = otherCustomMethod.__get__(window2, WindowGeneric) #bind to instance

但是这个解决方案看起来也很难看,因为 get “黑客”的东西。

它实际上是关于对象的创建,窗口的元素在运行时之前是已知的,并且在运行时不会改变。

那么还有更好的方法吗?

编辑: 澄清一点: 我只想创建许多相似但不相等的对象(它们内部可以有不同的方法和变量),但我不知道为每个对象(版本1)创建一个新类是否更好或创建对象通过具有虚拟对象并在之后添加单个功能(版本2)。

3 个答案:

答案 0 :(得分:0)

很难说你的代码片段,但也许你可以使用继承来解决这个问题......

class BaseWindow(object):
     def __init__(self,elements):
        self.elements = elements
     def common_method1(self,...):
        ...
     def common_method2(self,...):
        ...

class Window1(BaseWindow):
     def __init__(self):
        BaseWindow.__init__(self,{"button1":button1,"button2":button2,...})

答案 1 :(得分:0)

这里需要的是工厂模式。创建FactoryWindow类,并添加classmethod createwindow以基于某些Window ID实例化窗口。维护所有Windows实例化的字典,如果要实例化现有实例,则返回上一个实例而不是创建新实例

class FactoryWindow(object):
    Windows = {1:Window1,2:Window2}
    window_instance = {}
    @classmethod
    def CreateWindow(cls,win_no):
        if win_no in cls.window_instance:
            return cls.window_instance[win_no]
        else:
            cls.window_instance[win_no] = cls.Windows[win_no]()
            return cls.window_instance[win_no]


>>> window1 = FactoryWindow.CreateWindow(1)
>>> window2 = FactoryWindow.CreateWindow(2)
>>> window3 = FactoryWindow.CreateWindow(1)
>>> id(window3) == id(window1)
True

答案 2 :(得分:0)

尽可能将演示文稿与逻辑分开通常更清晰。

考虑一个通用窗口,它只是/大部分是接口元素的哑容器,加上你需要的任何回调(它们只能是传递给__init__方法的函数或可调用对象,你不需要从外部攻击对象的新方法。

这意味着:

  • 如果你有很多,你可以轻松地从config(XML或其他)构建你的哑窗口,从而避免将硬编码的布局信息与你的逻辑混合
  • 您可以轻松地模拟窗口,或直接调用您的回调,以便在不显示GUI元素的情况下运行测试
  • 如果需要
  • ,您可以更轻松地移植到不同的GUI系统