возвращать пользовательский экземпляр из класса без потери доступа к исходному экземпляру - PullRequest
0 голосов
/ 03 октября 2018

У меня есть такой класс:

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 голосов
/ 03 октября 2018

Мне удается решить ее, используя функцию для создания класса:

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 за то, что он показал мне правильное направление

0 голосов
/ 03 октября 2018

Если вы хотите, чтобы Item экземпляр был Gtk.Entry, то наследуйте ваш класс от Gtk.Entry

class Item(Gtk.Entry):
    ...

С другой стороны, если вы хотите, чтобы ваш класс наследовал от другого динамически, вы должныиспользовать метакласс.

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')
...