Python 多类vs多对象

Python 多类vs多对象,python,class,object,creation,Python,Class,Object,Creation,我正在从事一个Python项目,其中我必须在代码中表示GUI结构。 看起来是这样的: 窗口1(包含按钮1、按钮2、按钮3、对话框1等) 窗口2(包含按钮4、按钮5、对话框2、列表1等) 因此有许多窗口,每个窗口都有不同的内容,在不同的元素后面有不同的功能。每个窗口可以有不同的自定义方法,这些方法只能在那里使用 现在我有两种可能性: 第一: class Window1(object): def __init__(self): self.elements = {"butt

我正在从事一个Python项目,其中我必须在代码中表示GUI结构。 看起来是这样的:

  • 窗口1(包含按钮1、按钮2、按钮3、对话框1等)
  • 窗口2(包含按钮4、按钮5、对话框2、列表1等)
因此有许多窗口,每个窗口都有不同的内容,在不同的元素后面有不同的功能。每个窗口可以有不同的自定义方法,这些方法只能在那里使用

现在我有两种可能性:

第一:

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
但是这个解决方案看起来也很难看,因为“黑客”的东西

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

那么,有没有更好的方法

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

很难用您的代码片段来判断,但也许您可以使用继承来解决此问题

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,...})

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

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

尽可能多地将表示与逻辑分离通常更干净

考虑一个通用窗口,它只是/主要是接口元素的哑容器,加上您需要的任何回调(它们可以是传递到
\uuuuu init\uuuuu
方法的函数或可调用对象,您不需要从外部将新方法植入对象)

这意味着:

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

这将是解决方案1,因此我将使用Window1到WindowN的类,每个类只有一个实例。我不知道这是否是最好的方法,但是我仍然需要定义所有的窗口类,如果可能的话,我不想为每个窗口创建一个新的类,至少不能手工创建。