Как мне украсить метод __init__ с помощью Click? - PullRequest
0 голосов
/ 25 апреля 2020

Я часто использую следующий шаблон, где я создаю экземпляр объекта Main, обычно для пакета, а затем вызываю process() для него. Все необходимые опции передаются в __init__. Это означает, что, если я создаю Main с соответствующими параметрами, я могу запустить его из любого места (например, сельдерей ).

(я научился сводить к минимуму отладку в сельдерее до максимальной степени, чтобы сохранить здравомыслие - сначала сценарии полностью отлаживаются из командной строки, и только потом создаются и запускаются сети из сельдерея)

Это мой рабочий Нажмите Подход:

Довольно просто. декорированная функция run определяет свои аргументы и передает их Main.__init__.

Концептуально, однако, run и его строка документации очень отделены от этого __init__. Поэтому на __init__ я должен посмотреть на run, чтобы понять, что передать, и когда я --help из командной строки, я получаю строку документации для run.

import click

@click.command()
@click.option('--anoption')
def run(**kwargs):
    mgr = Main(**kwargs)
    mgr.process()

class Main:

    def __init__(self, **kwargs):
        self.__dict__.update(**kwargs)

    def process(self):
        print(f"{self}.process({vars(self)})")

if __name__ == "__main__":
    run()

output:

<__main__.Main object at 0x10d5e42b0>.process({'anoption': None})

Это то, что я хотел бы вместо этого:

import click

class Main:

    @click.command()
    @click.option('--anoption')
    def __init__(self, **kwargs):
        self.__dict__.update(**kwargs)

    def process(self):
        print(f"{self}.process({vars(self)})")

if __name__ == "__main__":
    main = Main(standalone_mode=False)
    main.process()

Но это заставляет меня TypeError: __init__() missing 1 required positional argument: 'self'

Используя factory метод

самый близкий, который я приехал, с фабричным статическим методом, но это не здорово. По крайней мере, фабрика сидит на классе, но все еще не так много ссылок на вывод init .

import click

class Main:

    @staticmethod
    @click.command()
    @click.option('--anoption')
    def factory(**kwargs):
        return Main(**kwargs)

    def __init__(self, **kwargs):
        self.__dict__.update(**kwargs)

    def process(self):
        print(f"{self}.process({vars(self)})")

if __name__ == "__main__":
    main = Main.factory(standalone_mode=False)
    main.process()

:

<__main__.Main object at 0x10ef59128>.process({'anoption': None})

Что такое простой Pythoni c способ приблизить click и что Main.__init__ ближе друг к другу?

...