2013-03-11 73 views
1

所以你有一些功能,比如Gtk.Builder.get_object(),它返回一些小部件。在我们的案例中,一个Gtk.Window()从超类实例构造类

我有一个Gtk.Window()的子类,它增加了一些信号处理程序。

class Window(Gtk.Window): 

是否有可能使用由Gtk.Builder.get_object()返回的小部件来构建Window()?我认为它应该使用__new__()什么的,但我无法弄清楚。

+0

您可以写入您正在获取的'Gtk.Window'实例的'__class__'属性吗? – Blckknght 2013-03-11 03:58:49

+0

@Blckknght安全吗?我在'__new __()'中设置了'window .__ class__ = cls'的快速测试。我似乎能够从这个子类调用方法,但是'__init__'仍然没有运行。根据我对文档的理解,它应该如此,所以IDK。 – ABP 2013-03-11 04:26:34

+0

只要您设置的类是实例上一个类的子类,它就应该是安全的。我不确定为什么如果你从'__new__'返回修改后的实例,它不会调用'__init__'。我会把这个建议写成答案,但在我们弄清楚发生了什么问题之前,请随时不要接受它。 – Blckknght 2013-03-11 04:53:24

回答

1

我认为使用__new__正是你想要做的。如果您可以设置您获得子类的超类实例的__class__属性,则应该全部设置。

这就是我想你需要:

class Window(Gtk.Window): 
    def __new__(cls, *args, **kwargs): 
     self = Gtk.Builder.get_object() 
     self.__class__ = cls 
     return self 

Python的应该检测,是由__new__创造的价值是类的一个实例(感谢__class__值),则它会调用__init__等适当的方法。

+0

@ABP - 这应该起作用。在CPython中,可以安全地为具有兼容内存布局的堆类型实例重新分配'__class__',该内存布局在运行时检查。如果'__init__'没有运行,则元类'__call__'方法必须被覆盖。 – eryksun 2013-03-11 05:12:42

+0

好吧,这似乎确实工作,实际上。我定义了新的像'def __ new __(cls,data_dir)'并创建了像Window.__ new __(Window,'..')这样的对象,但是这必须是不正确的。 – ABP 2013-03-11 05:44:13

+0

我刚刚检查过,'gobject.GObjectMeta'不会覆盖'type .__ call__'。 – eryksun 2013-03-11 05:44:40