return 来自 class 的自定义实例,不会失去对原始实例的访问权限

return custom instance from class without lost access to original instance

我有一个 class 这样的:

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.: 'children' 可以是任何 Gtk.Widget

如果您希望 Item 实例成为 Gtk.Entry,则从 Gtk.Entry

继承您的 class
class Item(Gtk.Entry):
    ...

另一方面,如果您希望 class 从另一个动态继承,您应该使用 metaclass。

class ItemFactory:
    @staticmethod
    def create_from(label, target):
        return type('Item', (target,), dict(label=label))


item = ItemFactory.create_from('label', Gtk.Entry)
item.set_text('text')
item.label.set_text('text')

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

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 为我指明了正确的方向