У меня есть этот код, который отлично работает:
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.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, после вызова обработчика команды параметры и аргументы являются просто их необходимыми значениями и больше не являются объектами щелчка.
Это связано с как работают декораторы. Вы применили многие из них к
click, и, предположительно, ваш вызов методаmain()проходит через все эти декораторы, прежде чем фактически достигнет тела функцииmain(). И каждый из декораторовclickдобавляет один параметр по умолчанию, так как он не был указан в вашем первоначальном вызове. Таким образом, к тому времени, когда вы приступите к фактическому вызовуmain(), декораторы уже предоставили все аргументы по умолчанию.