将命令行参数传递给runpy

7

我有两个文件,其中一个在if __name__ == "__main__"保护内发生了我关心的副作用:

# 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
在调用runpy之前如何模拟sys.argv,或以其他方式将该值提供给a.py

什么是“进程”? - U13-Forward
process 是由 a.py 的作者编写的任意代码,超出了我的控制范围。它可能不是一个函数,而是一堆语句。重点是在更新字典之前,sys.argv[1] 被用作进一步处理的输入。 - Alex Shroyer
runpy.run_module 不会返回一个包含 arg 的字典。你确定代码是正常工作的吗?还是它只是偶然模拟了参数? - asn-0184
1
你说得对,我打错了字。runpy.run_module返回一个键为d的模块,所以上面应该是m['d'] - Alex Shroyer
@asn-0184,感谢您的评论,我已根据您的建议更新了问题。 - Alex Shroyer
2个回答

3
这可能太简单了吧?我几乎是偶然间找到了这个解决方案。
$ python3 b.py foo
{'arg': 'foo'}

似乎在从命令行调用b.py时,sys.argv [1]会传递到a中。

编辑

以下是来自我的shell的示例会话:

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'}

2
也许在特定的上下文中这可以运行,但是如果我想让 b.py 根据一些其他逻辑"选择"要发送给 a.py 的命令行参数呢? - Jake Stevens-Haas

1

如果您像我一样偶然发现了这篇文章,您可以直接传递命令行参数。举个例子,如果我有以下命令:

# 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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接