У меня есть скрипт Python 3, который выглядит так:
...
def main():
parser = argparse.ArgumentParser(description='Perform normalisation checks on pass2 files')
parser.add_argument('-p', '--parser', action='store', help='parser_code.', default = "")
parser.add_argument('-m', '--midnight', help='start of day '
'in ns UTC', type=int, default=0)
parser.add_argument('file', help='File to validate')
args = parser.parse_args()
rc = ReturnCode.SUCCESS
rc = do_checks(args.file, args.midnight, args.parser)
print(f"Validation completed with status: {rc}")
exit(rc)
if __name__ == '__main__':
main()
Обычно я запускаю этот скрипт в командной строке, передавая имя файла в качестве аргумента, что-то вроде:
python3 /util/check_normalisation.py -p lse /home/pchong/work/algotick/new_lob/pass2/01/97756_20240701.h5
Однако теперь у меня есть каталог, полный файлов (тысячи файлов), для которых я хотел бы запустить этот сценарий.
И мне сложно «запустить этот сценарий» из другого сценария, который я создаю. Можно ли сделать это?
Вот схема моего сценария:
directory = '<path_to_directory_with_files_I_would_like_to_run_script_against'
for file in os.listdir(directory):
filename = os.fsdecode(file)
run_the_above_script(filename) # this is where I don't know what to do to run the command line python script
Почему бы не создать оригинальную функцию main
, которая будет принимать аргументы и использовать argparse
только для подачи этих аргументов if __name__ == '__main__'
?
Попался, не подумал об этом. Спасибо. Единственное, что если у меня тысячи файлов, я бы передал все эти имена файлов в качестве аргументов?
Вы передаете эти аргументы (например, filename
) в цикл for: желаемый run_the_above_script(filename)
станет main(filename)
(возможно, с лучшим именем). Таким образом, ваш оригинальный скрипт может работать как модуль, так и как отдельная программа.
Я предлагаю улучшить ваш скрипт, чтобы он мог принимать несколько файлов и последовательно делать то, что он должен делать. Вы можете использовать nargs='+'
в argparse
, чтобы выразить одно или несколько, рассмотрите следующий простой пример: пусть fnprinter.py
будет
import argparse
parser = argparse.ArgumentParser(description = "Filenames printer")
parser.add_argument("--prefix", help = "will be printed before each filename", default = "")
parser.add_argument("files", help = "filenames", nargs = "+")
args = parser.parse_args()
for file in args.files:
print(args.prefix, file)
затем
python fnprinter.py --prefix foobar file1.txt file2.txt file3.txt
дает результат
foobar file1.txt
foobar file2.txt
foobar file3.txt
Хотя ваше предложение является улучшением исходной конструкции, оно не отвечает на вопрос.
Спасибо за это! Я вижу здесь улучшение дизайна. Единственное, если у меня тысячи файлов, я не знаю, как их передать, если не наберу каждый вручную.
Для этого вы можете использовать subprocess.run
. Пример:
import subprocess
subprocess.run(["python", "script_name.py", "arg1", "arg2", ...])
Вы можете ознакомиться с документацией по управлению подпроцессами Python здесь.
Взгляните на модуль подпроцесса