Аргументы командной строки для основной функции при использовании клика

У меня есть этот код, который отлично работает:

import click

@click.command(context_settings=dict(help_option_names=['-h', '--help']))
@click.option('--team_name', required=True, help='Team name')
@click.option('--input_file', default='url_file.txt', help='Input file name for applications, URLs')
@click.option('--output_file', default='test_results_file.txt', help='Output file name to store test results')
def main(team_name, input_file, output_file):
    # function body

if __name__ == '__main__':
    main()                  # how does this work?

Как видите, main вызывается без аргументов, хотя должно получить три. Как это работает?

Это связано с как работают декораторы. Вы применили многие из них к click, и, предположительно, ваш вызов метода main() проходит через все эти декораторы, прежде чем фактически достигнет тела функции main(). И каждый из декораторов click добавляет один параметр по умолчанию, так как он не был указан в вашем первоначальном вызове. Таким образом, к тому времени, когда вы приступите к фактическому вызову main(), декораторы уже предоставили все аргументы по умолчанию.

Green Cloak Guy 15.07.2019 21:06
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
3
1
1 031
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Как упоминалось в комментариях, об этом позаботятся декораторы. Декоратор click.command превращает функцию в экземпляр click.Command.

Каждый из декораторов вариантов создает экземпляр click.Option и прикрепляет его к объекту click.Command для последующего использования.

Этот объект click.Command реализует __call__ метод, который вызывается вашим вызовом main().

def __call__(self, *args, **kwargs):
    """Alias for :meth:`main`."""
    return self.main(*args, **kwargs)

Это довольно просто и просто вызывает click.Command.main().

В верхней части click.Command.main() находится:

if args is None:
    args = get_os_args()
else:
    args = list(args)

Этот код получает argv из командной строки или использует предоставленный список аргументов. Дальнейший код в этом методе, среди прочего, анализирует командную строку в контексте и, в конечном итоге, призвание твоего main() со значениями из созданных ранее экземпляров click.Option:

with self.make_context(prog_name, args, **extra) as ctx:
    rv = self.invoke(ctx)

Это источник загадочных 3 аргументов.

Кстати, те же правила применяются при использовании click.argument?

zygimantus 10.11.2019 11:09

@zygimantus, после вызова обработчика команды параметры и аргументы являются просто их необходимыми значениями и больше не являются объектами щелчка.

Stephen Rauch 10.11.2019 16:42

Другие вопросы по теме