передача аргументов командной строки в runpy

#python #python-3.x

#python #python-3.x

Вопрос:

У меня есть два файла, один из которых имеет побочный эффект, о котором я забочусь, который возникает внутри if __name__ == "__main__" guard:

 # a.py
d = {}
if __name__ == "__main__":
    d['arg'] = 'hello'
 

Второй файл импортирует первый (используя runpy ) и печатает словарь:

 # b.py
import runpy
m = runpy.run_module('a', run_name='__main__')
print(m['d'])  # {'arg': 'hello'}
 

Пока это работает. Но теперь я хочу изменить первый файл, чтобы он принимал аргумент командной строки:

 import sys
d = {}
if __name__ == "__main__":
    d['arg'] = process(sys.argv[1])
 

Проблема в том, что process() это написано кем-то другим и вне моего контроля, но я все равно хочу получить обновленный словарь d после его «обработки».

Как я могу издеваться sys.argv перед вызовом runpy или иным образом предоставлять это значение a.py ?

Комментарии:

1. Что такое process ?

2. process это произвольный код, созданный автором a.py , вне моего контроля. Это может быть не функция, а набор операторов. Дело в том, что sys.argv[1] это используется в качестве входных данных для дальнейшей обработки перед обновлением словаря.

3. runpy.run_module не возвращает dict, содержащийся arg в ключах. Вы уверены, что код работает? Или это просто издевательство над аргументом?

4. Вы правы, у меня была опечатка. runpy.run_module возвращает модуль с ключом d , поэтому должно было быть указано выше m['d'] .

5. @asn-0184 Я обновил вопрос в ответ на ваш комментарий, спасибо.

Ответ №1:

Может ли это быть так просто? Я нашел это решение почти случайно.

 $ python3 b.py foo
{'arg': 'foo'}
 

Кажется, что sys.argv[1] это передается a даже тогда, когда b.py вызывается из командной строки.

Редактировать

вот пример сеанса из моей оболочки:

 me@desktop$ cat a.py b.py
import sys
d = {}
filename = sys.argv[1]
if __name__ == "__main__":
    d['result'] = filename   ' world'


# usage:
# python3 b.py filename
# 'filename' is passed in to the a module
import runpy
aa = runpy.run_module('a', run_name='__main__')
print(aa['d'])  # {}

me@desktop$ python3 b.py hello
{'result': 'hello world'}
 

Комментарии:

1. Возможно, это работает в конкретном контексте, но что, если я хочу b.py выбрать аргументы командной строки для отправки на a.py основе какой-либо другой логики?

Ответ №2:

Для тех, кто наткнулся на этот пост, как я, вы можете просто передать аргументы командной строки напрямую. В качестве примера, если у меня есть

 # a.py
import argparse

def parse_args():
    # fmt: off
    parser = argparse.ArgumentParser()
    parser.add_argument("--myvar")
    args = parser.parse_args()
    # fmt: on
    return args

if __name__ == "__main__":
    args = parse_args()
    print(args.myvar)
 
 # b.py

import runpy
runpy.run_path(path_name='a.py', run_name="__main__")
 

Я получаю

 $ python a.py 
None
$ python a.py --myvar test
test
$ python b.py 
None
$ python b.py --myvar test
test