你不能“调用它的主函数”,因为它没有。
事实上,处理这个问题的常用方法是将所有这些代码移动到一个函数中,然后让 __main__
保护代码调用它:
def main(args):
for key in args:
print(key)
if __name__ == '__main__':
main(sys.argv)
然后你可以调用它的主函数,传递你想要的任何参数。
但是如果你不能修复这个文件,那是行不通的。
那么,可以做什么呢?这完全取决于您需要在多大程度上遵循通常的python another.py
语义。
快速而肮脏的方法是执行blhsing's answer 建议的操作:读取文件,然后使用您自己的脚本中的globals exec
它:
with open('another.py') as f:
exec(f.read(), globals())
请注意,这将使sys.argv
保持不变。当然,您可以先手动将其设置为其他值:
_argv = sys.argv
sys.argv = ['args', 'i', 'want', 'it', 'to', 'see']
try:
with open('another.py') as f:
exec(f.read(), globals())
finally:
sys.argv = _argv
如果您是从另一个模块而不是从您的顶级脚本执行此操作,那将无法正常工作,但稍作修改后,它将:
with open('another.py') as f:
exec(f.read(), sys.modules['__main__'].__dict__)
但您最好创建一个干净的全局命名空间。脚本可能不希望让您的全局变量坐在那里——它可能会改变您不希望它改变的东西。这同样简单:
with open('another.py') as f:
exec(f.read(), {})
(请注意,这仍会自动继承当前的builtins
,这是您通常想要的。如果您出于某种原因不想要,请参阅exec
文档。)
如果您想保证执行它的方式与正常运行脚本的方式完全相同,请使用runpy
模块。
当你运行python -m another
时,它最终会做的是:
runpy.run_module(sys.argv[0], run_name="__main__", alter_sys=True)
所以,你可以手动做同样的事情:
runpy.run_module('another', run_name='__main__')
您是否要添加alter_sys=True
取决于您的目标。没有它,如果脚本尝试访问sys.argv
(就像您的脚本一样)或sys.modules['__main__']
,它将看到您的值,而不是它自己的值。
如果你想模拟python another.py
,你需要使用importlib
来创建一个完整的__spec__
和相关的对象,然后调用runpy.run_path
。