Почему subprocess.run не принимает список аргументов?

Я запускаю сценарий с именем mini_medsmaker.py, и в этом сценарии я использую subprocess.run для вызова другого сценария с именем mini_mocks.py.

Я использую argparse для перечисления своих аргументов, и это команда, которую я запускаю:

subprocess.run(["python", "/path/to/mini_mocks.py", *vars(args).values()])

Всякий раз, когда я запускаю его, я получаю эту ошибку:

Traceback (most recent call last):
  File "/work/mccleary_group/vassilakis.g/superbit-metacal/superbit_lensing/medsmaker/scripts/mini_medsmaker.py", line 86, in <module>
    rc = main(args)
  File "/work/mccleary_group/vassilakis.g/superbit-metacal/superbit_lensing/medsmaker/scripts/mini_medsmaker.py", line 81, in main
    subprocess.run(["python", "/work/mccleary_group/vassilakis.g/superbit-metacal/superbit_lensing/medsmaker/scripts/mini_mocks.py", *vars(args).values()])
  File "/work/mccleary_group/vassilakis.g/miniconda3/envs/sbclone2/lib/python3.7/subprocess.py", line 488, in run
    with Popen(*popenargs, **kwargs) as process:
  File "/work/mccleary_group/vassilakis.g/miniconda3/envs/sbclone2/lib/python3.7/subprocess.py", line 800, in __init__
    restore_signals, start_new_session)
  File "/work/mccleary_group/vassilakis.g/miniconda3/envs/sbclone2/lib/python3.7/subprocess.py", line 1482, in _execute_child
    restore_signals, start_new_session, preexec_fn)
TypeError: expected str, bytes or os.PathLike object, not list

Однако я подумал, что subprocess.run может принимать списки как объект? Как я могу это исправить?

Я попытался преобразовать его как в JSON, так и в строку, но тогда мой файл mini_mocks.py не может принять его в качестве аргумента.

Да, это может занять список. Но это должен быть список строк. Что-то в vars(args).values() — это список, а не строка.

Barmar 10.02.2023 19:14

Похоже, вы обрезали сообщение об ошибке и что сообщение не ссылается на единственную строку кода, которую вы разместили. Пожалуйста, опубликуйте полное сообщение об ошибке и, чтобы помочь в отладке, добавьте print([*vars(args).values()]), чтобы мы могли видеть данные.

tdelaney 10.02.2023 19:15

Просто введите полное сообщение об ошибке, позвольте мне попробовать распечатать аргументы.

George Vassilakis 10.02.2023 19:22

Добавьте что такое args - это класс?

CodeCop 10.02.2023 19:22

Здесь я добавляю аргументы: parser.add_argument('--mock_dir', type=str) parser.add_argument('--exposure_list', type=list) parser.add_argument('--outfile', type=str) parser.add_argument('-outdir', type=str, parser.add_argument('-fname_base', action='store', type=str, parser.add_argument('-run_name', action='store', type=str, parser.add_argument('--meds_coadd', action='store_true',\ parser.add_argument('--overwrite', action='store_true' parser.add_argument('--exposures_per_list', type=int return parser.parse_args()

George Vassilakis 10.02.2023 19:27

Кажется, вы предполагаете, что vars будет перечислять параметры в args определенным образом, но я не вижу, где это задокументировано.

tdelaney 10.02.2023 23:47
Почему в 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 может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
6
72
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

subprocess.run поддерживает список аргументов, однако, если список содержит что-то большее, чем строка, байты или os.PathLike объекты, он потерпит неудачу:

# subprocess.py: line 608 in the list2cmdline function

for arg in map(os.fsdecode, seq):
    bs_buf = []

Потому что метод os.fsdecode получает только имя файла в виде строк, байтов или os.PathLike, как указано выше, и возвращает декодированное имя файла. Здесь вы пытаетесь сопоставить каждый value словаря vars(...), и некоторые значения представляют собой списки (и, возможно, более нежелательные типы, такие как функции и т. д.), которые fsdecode не может выполнить.


Убедитесь, что вы уточняете каждое значение в *vars(A).values() таким образом, чтобы только упомянутые выше типы были в:

subprocess.run(["python", "./your_path.py", *filter(lambda x: type(x) in [str, bytes, os.PathLike], vars(args).values())])

Или, если вам нужна буквальная строка списка:

subprocess.run(["python", "./your_path.py", *map(str, vars(args).values())])

запуск вашего фильтра, который вы мне дали, позволил мне, наконец, передать аргументы в следующий скрипт. Теперь есть еще одна ошибка того же типа, но это проблема с другим скриптом, но этот ответ решает мою первоначальную проблему с передачей аргументов!

George Vassilakis 10.02.2023 19:44

@GeorgeVassilakis хорошо, это еще одна проблема сама по себе, и ее следует открыть как отдельный вопрос :-)

CodeCop 10.02.2023 19:52

Простое преобразование всего в строки — странное решение. Таким образом, список становится строковым представлением списка в Python, а флаг становится «Истинным»? Неважно, что теперь все позиционные аргументы без какой-либо заботы о порядке их передачи. Это может предотвратить сбой программы при этом вызове, но трудно понять, как это работает на самом деле.

tdelaney 10.02.2023 23:54

@tdelaney OP не указал, как эти параметры используются и по какой причине. Я дал «преобразовать все в строку» в качестве побочного решения, не зная, каково на самом деле намерение, хотя по первому впечатлению кажется, что ОП хочет, чтобы каждое значение словаря передавалось независимо от его типа.

CodeCop 11.02.2023 01:13

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

Как проверить, что все элементы списка имеют минимальную разницу x
Объединить два отсортированных массива с использованием цикла for, в котором отсутствует последний элемент
Как «stripPrefix», где префикс может быть одной из нескольких строк
Можно ли перебирать элементы в списке и возвращать фрагменты списка на основе повторяющихся символов?
Как проверить каждую тенденцию строки с некоторым допуском, игнорируя значения np.nan в фрейме данных pandas
Соберите элементы, из-за которых all() возвращает false
Как проверить, находится ли количество одинаковых последовательных чисел ниже порогового значения в серии pandas
Удалить числовые символы с начала строки в списке
Как сортировать элементы по нескольким критериям в Python?
Если элемент находится в списке, создайте новый список с именованным элементом + строка с такими же элементами в нем