Как вызвать метод Python, который ожидает аргументы CLI?

Не знаю, как еще это выразить, Но я конвертирую сценарий bash в python и пытаюсь вызвать метод в библиотеке python, который обычно вызывается через интерфейс командной строки. Этот метод использует argparse и при вызове ожидает 2 аргумента.

Я не уверен, как вызвать этот метод и предоставить два аргумента при вызове его из отдельного скрипта Python.

Что я пробовал:

>>  from somelibrary import mymethod as method
>>  method.main('foo', 'bar')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: main() takes 0 positional arguments 
but 2 were given

>>> method.main()
usage: [-h] foo bar
: error: the following arguments are required: 
foo, bar

Любая помощь приветствуется!

Было бы полезно посмотреть, как выглядит mymethod

Zac Brown 25.07.2018 22:20

Есть ли причина, по которой вы не запускаете модуль просто как команду CLI через модуль subprocess? Предположительно, main не возвращает ничего полезного, поэтому subprocess.run([sys.executable, '-m', 'somelibrary', 'foo', 'bar']) кажется простым решением ...

ShadowRanger 25.07.2018 22:25

Что вы пытаетесь вызвать? Вы контролируете это? Можете ли вы изменить его, чтобы принимать аргументы? Вы уверены, что нет более подходящей точки входа при использовании этого кода в качестве библиотеки?

user2357112 supports Monica 25.07.2018 22:27

@ user2357112 По сути, я вызываю метод, который принимает два аргумента: файл sqlite и файл tsv. Он заполнит базу данных sqlite содержимым файла tsv. Я не контролирую это. Я тоже не верю, что смогу это изменить.

Heidi Lyons 25.07.2018 23:13

@ user2357112 Обновить! Я поговорил с владельцем, и могу изменить его, чтобы он принимал аргументы. Я собираюсь сделать это

Heidi Lyons 25.07.2018 23:27
Почему в 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 может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
5
245
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

используйте sys.argv - он содержит аргументы, переданные скрипту py.

from somelibrary import mymethod as method
>>> sys.argv[1:] = ['foo', 'bar']
>>> method.main()

Это предполагает, что у sys.argv еще не было других аргументов. Замена содержимого, а не extending, скорее надежнее.

ShadowRanger 25.07.2018 22:23

@ShadowRanger OP тестирует код в интерпретаторе - я уверен, что у него больше нет аргументов

nosklo 25.07.2018 22:25
$ ipython3 --classic, >>> sys.argv продуцирует ['/path/to/ipython3', '--classic']. И даже если этого не произошло, интерактивный интерпретатор часто используется для тестирования того, что вы хотите использовать в сценарии позже. Новый подход, который вы использовали при редактировании, в общем случае более безопасен.
ShadowRanger 25.07.2018 22:30

Круто, это работает! Однако когда я его реализую, он будет вызываться из задачи celery в django. Не уверены, что это кардинально изменит ситуацию?

Heidi Lyons 25.07.2018 22:33
Ответ принят как подходящий

Эта функция почти наверняка вызывает метод Argparser.parse_args() без аргументов Python:

parser.parse_args()

Это берет аргументы из Список sys.argv, принимая все элементы, кроме первого.

sys.argv - это просто список, поэтому вы можете создать свой собственный:

import sys
from somelibrary import mymethod as method

sys.argv[1:] = ['foo', 'bar']
method()

Предпочтительно, если вы можете изменить этот проект или предложить изменения, вам следует (попросить) обновить функцию main(), чтобы она принимала аргументы:

def main(args=None):
    if args is None:
        args = sys.argv[1:]

    # ...

    parser.parse_args(args)

Возможно, вам придется рассмотреть возможность того, что сценарий не предназначен для импорта в другую программу (он может изменить глобальное состояние, на которое полагаются другие части вашей программы, или он может закончиться sys.exit() и, таким образом, закрыть вашу программу, если вы специально не поймаете Исключение SystemExit. Возможно, будет проще просто запустить сценарий в качестве дочернего процесса, используя:

import sys
import subprocess

result = subprocess.run([sys.executable, '/path/to/somelibrary', 'foo', 'bar'])

Я бы хотел услышать, что в моем ответе не помогает или нет, чтобы заслужить отрицательный голос. Так я смогу улучшить свой ответ!

Martijn Pieters 25.07.2018 22:27

Спасибо Мартейн Питерс! Я выбрал этот вариант как лучший ответ, потому что в итоге получил разрешение на изменение main, чтобы принимать аргументы.

Heidi Lyons 25.07.2018 23:29

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