【问题标题】:Construct class from superclass instance从超类实例构造类
【发布时间】:2013-03-11 03:32:53
【问题描述】:

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

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

class Window(Gtk.Window):

是否可以使用Gtk.Builder.get_object()返回的小部件来构造Window()?我想应该是用__new__()什么的,但我想不通。

【问题讨论】:

  • 你能写到你得到的Gtk.Window 实例的__class__ 属性吗?
  • @Blckknght 那安全吗?我做了一个快速测试,我在__new__() 中设置了window.__class__ = cls。我似乎能够从子类中调用方法来执行此操作,但 __init__ 仍然没有运行。根据我对文档的解释,它应该是 IDK。
  • 只要你设置的类是实例上一个类的子类就应该是安全的。如果您从__new__ 返回修改后的实例,我不确定为什么它不会调用__init__。我将把这个建议写出来作为答案,但在我们弄清楚出了什么问题之前不要接受它。

标签: inheritance constructor python-3.x pygobject


【解决方案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__ 和其他适当的方法。

【讨论】:

  • @ABP - 这应该可以。在 CPython 中,您可以安全地为具有兼容内存布局的堆类型实例重新分配 __class__,这在运行时进行检查。如果__init__ 没有运行,则必须重写元类__call__ 方法。
  • 好的,这似乎确实有效。我定义了def __new__(cls, data_dir)之类的新对象,并创建了Window.__new__(Window, '..')之类的对象,但这一定是不正确的。
  • 我刚刚检查过,gobject.GObjectMeta 没有覆盖type.__call__
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-29
相关资源
最近更新 更多