假设我在python控制台中,并且希望在同一过程中启动另一个python程序。 python程序如下所示:
StackPanel
并且我不允许对其进行修改。
执行此操作的正确方法是什么?我可以使用其他参数列表(例如C ++或Java)将其称为“主函数”吗?
我不反对方法被认为是黑客。 Python是一种高度可扩展的解释语言,我将尽一切必要绕过此限制
答案 0 :(得分:2)
您可以读取文件并使用exec
来使用当前全局变量执行代码,以便__name__ == '__main__'
为真。
exec(open('file.py').read(), globals())
答案 1 :(得分:2)
您不能“调用其主要功能”,因为它没有一个。
实际上,处理此问题的通常方法是将所有这些代码移入一个函数,然后使__main__
保护代码仅调用该代码即可。
def main(args):
for key in args:
print(key)
if __name__ == '__main__':
main(sys.argv)
然后您可以调用其主函数,并向其传递所需的任何args。
但是,如果您无法修复文件,那将无法正常工作。
那么,您可以做什么 ?这完全取决于您需要如何遵循通常的python another.py
语义。
快速而肮脏的方法是按照blhsing's answer的建议进行操作:读取文件,然后通过您自己的脚本中的exec
来globals:
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
。