Как использовать python argparse с args, отличным от sys.argv?

Я по всей документации, и кажется, что нет способа сделать это, но:

Есть ли способ использовать argparse с любым списком строк, а не только с sys.argv?

Вот моя проблема: у меня есть программа, которая выглядит примерно так:

# This file is program1.py
import argparse

def main(argv):
    parser = argparse.ArgumentParser()
    # Do some argument parsing

if __name__ == '__main__':
    main(sys.argv)

Это отлично работает, когда эта программа вызывается прямо из командной строки. Однако у меня есть еще один python script, который запускает пакетные версии этого script с разными аргументами командной строки, которые я использую следующим образом:

import program1

arguments = ['arg1', 'arg2', 'arg3']
program1.main(arguments)

Я все еще хочу иметь возможность анализировать аргументы, но argparse автоматически по умолчанию использует sys.argv вместо аргументов, которые я им даю. Есть ли способ передать список аргументов вместо использования sys.argv?

Ответ 1

Вы можете передать список строк в parse_args:

parser.parse_args(['--foo', 'FOO'])

Ответ 2

Просто измените script на значение по умолчанию на sys.argv[1:] и проанализируйте аргументы без вывода первого (который является именем вызываемой команды)

import argparse,sys

def main(argv=sys.argv[1:]):
    parser = argparse.ArgumentParser()
    # Do some argument parsing
    args = parser.parse_args(argv)

if __name__ == '__main__':
    main()

Или, если вы не можете опустить первый аргумент:

import argparse,sys

def main(args=None):
    # if None passed, uses sys.argv[1:], else use custom args
    parser = argparse.ArgumentParser()
    parser.add_argument("--level", type=int)
    args = parser.parse_args(args)

    # Do some argument parsing

if __name__ == '__main__':
    main()

Последний: если вы не можете изменить вызываемую программу, вы все равно можете что-то сделать

Предположим, что программа, которую вы не можете изменить, называется argtest.py (я добавил вызов для печати аргументов)

Затем просто измените локальное значение argv модуля argtest.sys:

import argtest
argtest.sys.argv=["dummy","foo","bar"]
argtest.main()

выход:

['dummy', 'foo', 'bar']