Не знаю, как еще это выразить, Но я конвертирую сценарий 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
Любая помощь приветствуется!
Есть ли причина, по которой вы не запускаете модуль просто как команду CLI через модуль subprocess? Предположительно, main не возвращает ничего полезного, поэтому subprocess.run([sys.executable, '-m', 'somelibrary', 'foo', 'bar']) кажется простым решением ...
Что вы пытаетесь вызвать? Вы контролируете это? Можете ли вы изменить его, чтобы принимать аргументы? Вы уверены, что нет более подходящей точки входа при использовании этого кода в качестве библиотеки?
@ user2357112 По сути, я вызываю метод, который принимает два аргумента: файл sqlite и файл tsv. Он заполнит базу данных sqlite содержимым файла tsv. Я не контролирую это. Я тоже не верю, что смогу это изменить.
@ user2357112 Обновить! Я поговорил с владельцем, и могу изменить его, чтобы он принимал аргументы. Я собираюсь сделать это






используйте sys.argv - он содержит аргументы, переданные скрипту py.
from somelibrary import mymethod as method
>>> sys.argv[1:] = ['foo', 'bar']
>>> method.main()
Это предполагает, что у sys.argv еще не было других аргументов. Замена содержимого, а не extending, скорее надежнее.
@ShadowRanger OP тестирует код в интерпретаторе - я уверен, что у него больше нет аргументов
$ ipython3 --classic, >>> sys.argv продуцирует ['/path/to/ipython3', '--classic']. И даже если этого не произошло, интерактивный интерпретатор часто используется для тестирования того, что вы хотите использовать в сценарии позже. Новый подход, который вы использовали при редактировании, в общем случае более безопасен.
Круто, это работает! Однако когда я его реализую, он будет вызываться из задачи celery в django. Не уверены, что это кардинально изменит ситуацию?
Эта функция почти наверняка вызывает метод 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'])
Я бы хотел услышать, что в моем ответе не помогает или нет, чтобы заслужить отрицательный голос. Так я смогу улучшить свой ответ!
Спасибо Мартейн Питерс! Я выбрал этот вариант как лучший ответ, потому что в итоге получил разрешение на изменение main, чтобы принимать аргументы.
Было бы полезно посмотреть, как выглядит
mymethod