从类返回自定义实例,而不会丢失对原始实例的访问

时间:2018-10-03 08:52:57

标签: python python-3.x gtk gtk3 python-3.7

我有一个这样的课程:

class Item:
    def __init__(self, name: str, label: str, children: Callable[..., Gtk.Widget]) -> None:
        self.label = Gtk.Label(label)
        [...]

        self._children = children()
        [...]

    def __getattr__(self, item):
        children = super().__getattribute__('_children')
        return children.__getattribute__(item)

所以我可以做这样的事情:

item = Item(name, 'label', Gtk.Entry)
item.set_text('text') # it'll return result from item._children.set_text
item.label.set_text('text') # it'll return result from item.label.set_text

但是我无法直接访问实例,因为它返回的是“ Item”实例,而不是“ children”实例:

print(type(item)) # it'll return <class 'Item'> instead <class 'Gtk.Entry'>

我尝试编写一个自定义__new__方法,但是似乎不可能在不失去对默认实例的访问权限的情况下将实例更改为_children(这样就无法访问item.label)。

有什么建议吗?

PS .:“子级”可以是任何Gtk.Widget

2 个答案:

答案 0 :(得分:1)

如果您希望type SyncHookDoc = (updateStore, doc: any, store) => (void | (doc: any) => any) 实例为Item,则从Gtk.Entry继承您的类

Gtk.Entry

另一方面,如果要让您的类动态继承自另一个类,则应使用元类。

class Item(Gtk.Entry):
    ...

答案 1 :(得分:1)

我设法使用创建类的函数来解决它:

def item_factory(children: Callable[..., Gtk.Widget]) -> Any:
    class Item(children):
        def __init__(self, name: str, label: str) -> None:
            super().__init__()

            self.label = Gtk.Label(label)
            [...]

    return Item

item = item_factory(Gtk.Entry)(name, label)
item.set_text('text')
item.label.set_text('text')
print(type(item)) # return <class 'Gtk.Entry'>

简单漂亮

感谢@Ramazan Polat向我展示了正确的方向