Я запускаю сценарий с именем 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 не может принять его в качестве аргумента.
Похоже, вы обрезали сообщение об ошибке и что сообщение не ссылается на единственную строку кода, которую вы разместили. Пожалуйста, опубликуйте полное сообщение об ошибке и, чтобы помочь в отладке, добавьте print([*vars(args).values()])
, чтобы мы могли видеть данные.
Просто введите полное сообщение об ошибке, позвольте мне попробовать распечатать аргументы.
Добавьте что такое args
- это класс?
Здесь я добавляю аргументы: 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()
Кажется, вы предполагаете, что vars
будет перечислять параметры в args
определенным образом, но я не вижу, где это задокументировано.
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())])
запуск вашего фильтра, который вы мне дали, позволил мне, наконец, передать аргументы в следующий скрипт. Теперь есть еще одна ошибка того же типа, но это проблема с другим скриптом, но этот ответ решает мою первоначальную проблему с передачей аргументов!
@GeorgeVassilakis хорошо, это еще одна проблема сама по себе, и ее следует открыть как отдельный вопрос :-)
Простое преобразование всего в строки — странное решение. Таким образом, список становится строковым представлением списка в Python, а флаг становится «Истинным»? Неважно, что теперь все позиционные аргументы без какой-либо заботы о порядке их передачи. Это может предотвратить сбой программы при этом вызове, но трудно понять, как это работает на самом деле.
@tdelaney OP не указал, как эти параметры используются и по какой причине. Я дал «преобразовать все в строку» в качестве побочного решения, не зная, каково на самом деле намерение, хотя по первому впечатлению кажется, что ОП хочет, чтобы каждое значение словаря передавалось независимо от его типа.
Да, это может занять список. Но это должен быть список строк. Что-то в
vars(args).values()
— это список, а не строка.