Я пытаюсь понять, как включить argparse в созданную мной функцию Python, которая принимает два аргумента, чтобы ее можно было выполнить в командной строке.
Например, в этой функции ниже:
def function(arg1, arg2):
print(arg1 * arg2)
Как я могу реализовать argparse, чтобы иметь возможность выполнять в командной строке следующее:
% python3 pythonscript.py function arg1 arg2
Я пытался использовать argparse, но нашел только руководства по его использованию в сценариях Python, а не в функциях.
Я не понимаю вашей проблемы - чтобы пробежать function
, нужно бежать script
. И это script
должно получить args
(например, используя sys.argv
или argparse
) и выполнить function
с помощью этих args
.
Кстати: return
не нужен =
. И если вы хотите увидеть результат в командной строке, вам нужно использовать print()
вместо return
.
@Grismar Хотя я в основном согласен, argparse
предоставит пользователю необходимую помощь, поэтому проверка кода пользователем не требуется. В частности, click — это библиотека, которая четко сочетает argparse
с функциями, как того хочет OP. Тем не менее, я считаю, что OP нужно больше основ Python, и ему следует сохранить click
на тот случай, когда они поймут больше о том, как работает Python и его скрипты.
Чтобы запустить функцию, вам необходимо загрузить скрипт, и этот скрипт должен получить аргументы и использовать их для выполнения ожидаемой функции с ожидаемыми значениями.
Чтобы получить аргументы, вы можете использовать sys.argv
, argparse
, и ему нужно будет распознать имя функции и запустить ее. Другие модули — такие как click , google/python-fire , вызвать — могут упростить задачу, поскольку они могут автоматически распознавать функцию и выполнять ее.
Для начала я показываю пример с sys.argv
import sys
"""
% python3 script.py mul 1 2
% python3 script.py add 1 2
"""
def mul(arg1, arg2):
return arg1 * arg2
def add(arg1, arg2):
return arg1 + arg2
# --- main ---
if len(sys.argv) < 4:
print("Usage: python3 script.py function arg1 arg2")
exit(1)
name = sys.argv[1]
val1 = int(sys.argv[2])
val2 = int(sys.argv[3])
if name == "mul":
result = mul(val1, val2)
print(result)
elif name == "add":
result = add(val1, val2)
print(result)
else:
print("wrong function's name")
И то же самое со словарем (вместо множества if/else) для выполнения функции:
import sys
"""
% python3 script.py mul 1 2
% python3 script.py add 1 2
"""
def mul(arg1, arg2):
return arg1 * arg2
def add(arg1, arg2):
return arg1 + arg2
# --- main ---
if len(sys.argv) < 4:
print("Usage: python3 script.py function arg1 arg2")
exit(1)
name = sys.argv[1]
val1 = int(sys.argv[2])
val2 = int(sys.argv[3])
functions = {
"mul": mul,
"add": add,
}
if name in functions:
result = functions[name](val1, val2)
print(result)
else:
print("wrong function's name")
И аналогично для argparse
.
argparse
может использовать опции, позволяющие отправлять более сложные параметры — например, пропускать параметры для использования значений по умолчанию и т. д. — поэтому это более полезно, чем sys.argv
Я добавил опцию --debug
для отображения дополнительной информации.
import argparse
"""
% python3 script.py --help
% python3 script.py mul 1 2
% python3 script.py add 1 2
% python3 script.py -D mul 1 2
% python3 script.py -D add 1 2
% python3 script.py --debug mul 1 2
% python3 script.py --debug add 1 2
"""
def mul(arg1, arg2):
return arg1 * arg2
def add(arg1, arg2):
return arg1 + arg2
# --- main ---
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('name')
parser.add_argument('val1')
parser.add_argument('val2')
parser.add_argument('-D', '--debug', action='store_true', help='[default: %(default)s]')
args = parser.parse_args()
if args.debug:
print("args:", args)
name = args.name
val1 = int(args.val1)
val2 = int(args.val1)
functions = {
"mul": mul,
"add": add,
}
if name in functions:
if args.debug:
print("executing:", functions[name], "with", val1, val2)
result = functions[name](val1, val2)
print(result)
else:
print("wrong function's name")
Если нажать , нажмите , это может быть проще, но нужно добавить декораторы.
#!/usr/bin/env python3
import click
"""
% python3 script.py mul 1 2
% python3 script.py add 1 2
"""
@click.group()
def cli():
pass
@click.command()
@click.argument('arg1', type=click.INT)
@click.argument('arg2', type=click.INT)
def mul(arg1, arg2):
print(arg1 * arg2)
@click.command()
@click.argument('arg1', type=click.INT)
@click.argument('arg2', type=click.INT)
def add(arg1, arg2):
print(arg1 + arg2)
cli.add_command(mul)
cli.add_command(add)
# --- main ---
cli()
То же самое и с огнем, может быть ещё проще
import fire
"""
% python3 script.py mul 1 2
% python3 script.py add 1 2
"""
class Calculator:
def mul(self, arg1, arg2):
return arg1 * arg2
def add(self, arg1, arg2):
return arg1 + arg2
# --- main ---
fire.Fire(Calculator)
Спасибо, это именно то, что я искал.
Делай это так:
import sys
def function(arg1, arg2):
return arg1 * arg2
if __name__ == '__main__':
args = sys.argv[1:]
function(*args)
Однако невозможно вызвать объект функции Python через командную строку. Через командную строку можно запускать только файлы Python и сценарии или другие исполняемые файлы. В приведенном выше коде аргументы сначала анализируются переменной sys
библиотеки .argv
, которая представляет собой список (здесь нет необходимости использовать argparse). Затем аргументы разрезаются на [1:]
, удаляя первый аргумент, который обычно является путем к файлу. Наконец, аргументы распаковываются и передаются в функцию по строке function(*args)
. Весь этот код окружен проверкой if __name__ == '__main__':
, которая необходима для определения того, выполняется ли этот файл напрямую или просто импортируется (в этом случае мы не хотим, чтобы блок выполнялся).
Чего именно вы пытаетесь достичь? Единственное применение
argparse
— это обработка аргументов командной строки в скрипте Python, он не имеет ничего общего с функциями. Конечно, вы можете создать сценарий, который при выполнении вызывает функцию с некоторыми из этих аргументов, но имена параметров не обязательно должны относиться к функциям, находящимся на самом деле в вашем сценарии. Плохая практика заставлять пользователя сценария, который необходимо использовать, из CLI, знать о содержимом вашего сценария и используемых в нем именах.