Search code examples
pythonpython-3.xgtkgtk3python-3.7

return custom instance from class without lost access to original instance


I have a class like that:

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)

So I can do things like that:

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

but I can't access instance directly because it's returning 'Item' instead 'children' instance:

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

I've tried to write a custom __new__ method but seems impossible to change instance to _children without lost access to the default instance (in this way I can't access item.label).

Any suggestion?

PS.: 'children' can be any Gtk.Widget


Solution

  • I manage to solve it using a function to create the 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'>
    

    simple and pretty

    thanks @Ramazan Polat for showing me the right direction