Inheritance 从超类实例构造类

Inheritance 从超类实例构造类,inheritance,constructor,python-3.x,pygobject,Inheritance,Constructor,Python 3.x,Pygobject,所以您有一些函数,比如Gtk.Builder.get_object(),它返回一些小部件。在我们的例子中,一个Gtk.Window() 我有一个子类Gtk.Window(),它添加了一些信号处理程序 class Window(Gtk.Window): 是否可以使用Gtk.Builder.get_object()返回的小部件来构造Window()?我认为应该使用\uuuu new\uuuuu()或其他什么,但我不明白。我认为使用\uuuuuuuu new\uuuuuu正是你想要做的。如果您可以设

所以您有一些函数,比如
Gtk.Builder.get_object()
,它返回一些小部件。在我们的例子中,一个
Gtk.Window()

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

class Window(Gtk.Window):

是否可以使用
Gtk.Builder.get_object()
返回的小部件来构造
Window()
?我认为应该使用
\uuuu new\uuuuu()
或其他什么,但我不明白。

我认为使用
\uuuuuuuu new\uuuuuu
正是你想要做的。如果您可以设置要访问子类的超类实例的
\uuuuuu class\uuuuu
属性,那么您应该已经全部设置好了

以下是我认为您需要的:

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

Python应该检测到由
\uuuuuu new\uuuuuu
创建的值是该类的一个实例(由于
\uuuuuuu class\uuuuuuuuuuu
值),然后它将调用
\uuuuuuu init\uuuuuuuuuuu
和其他适当的方法

我认为使用
\uuuu new\uuu
正是你想要做的。如果您可以设置要访问子类的超类实例的
\uuuuuu class\uuuuu
属性,那么您应该已经全部设置好了

以下是我认为您需要的:

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

Python应该检测到由
\uuuuuu new\uuuuuu
创建的值是该类的一个实例(由于
\uuuuuuu class\uuuuuuuuuuu
值),然后它将调用
\uuuuuuu init\uuuuuuuuuuu
和其他适当的方法

你能写入你得到的
Gtk.Window
实例的
\uuu class\uuuu
属性吗?@Blckknght安全吗?我在设置
窗口的地方做了一个快速测试。我似乎能够从这样做的子类中调用方法,但是
\uuuu init\uuu
仍然没有运行。根据我对文档的解释,它应该是安全的,所以IDK。只要您设置的类是实例的前一个类的子类,它就应该是安全的。如果您从
\uuuuu new\uuuuu
返回修改后的实例,我不确定它为什么不调用
\uuuuuuu init\uuuuu
。我将把这个建议写下来作为一个答案,但在我们找出问题所在之前,请不要接受它。你能写下你得到的
Gtk.Window
实例的
\uu class\uu
属性吗?@Blckknght安全吗?我在设置
窗口的地方做了一个快速测试。我似乎能够从这样做的子类中调用方法,但是
\uuuu init\uuu
仍然没有运行。根据我对文档的解释,它应该是安全的,所以IDK。只要您设置的类是实例的前一个类的子类,它就应该是安全的。如果您从
\uuuuu new\uuuuu
返回修改后的实例,我不确定它为什么不调用
\uuuuuuu init\uuuuu
。我将把这个建议写下来作为一个答案,但在我们找出问题所在之前,请不要接受它。@ABP-这应该行得通。在CPython中,您可以为具有兼容内存布局的堆类型的实例安全地重新分配
\uuuu class\uuu
,这将在运行时检查。如果
\uuuu init\uuuu
未运行,则必须重写元类
\uuuu调用\uuuuuuuu
方法。好的,实际上,这似乎是可行的。我定义了像
def\uuu new\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu(cls,data\uu dir)
这样的新对象,并创建了像
Window.uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。在CPython中,您可以为具有兼容内存布局的堆类型的实例安全地重新分配
\uuuu class\uuu
,这将在运行时检查。如果
\uuuu init\uuuu
未运行,则必须重写元类
\uuuu调用\uuuuuuuu
方法。好的,实际上,这似乎是可行的。我定义了像
def\uu new\uuuuuuuuuu(cls,data\u dir)
这样的新对象,并创建了像
Window.\uuuuu new\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu(Window,…)
)这样的对象,但这肯定。