从Python开始另一个程序>单独<

Sol*_*une 8 python subprocess

我正在尝试从Python运行一个外部的独立程序.这通常不是问题,但程序是游戏,并且内置了Python解释器.当我使用subprocess.Popen时,它启动单独的程序,但是在原始程序的Python实例下这样做,以便它们共享第一个Python控制台.我可以很好地结束第一个程序,但我宁愿有单独的控制台(主要是因为我有隐藏的控制台启动,但是当我使用subprocess.POpen从Python启动程序时会显示它).

如果我可以完全自己开始第二个程序,我想它就好像我只是"双击它".此外,os.system将无法工作,因为我的目标是跨平台兼容性,而且只能在Windows上使用.

aba*_*ert 6

如果我可以完全自己开始第二个程序,我想它就好像我只是"双击它".

从2.7和3.3开始,Python没有跨平台的方法来实现这一点.shutil.open将来可能会添加一种新方法(可能不在该名称下); 有关详细信息,请参阅http://bugs.python.org/issue3177.但在此之前,您必须为您关心的每个平台编写自己的代码.

幸运的是,您要做的事情比shutil.open最终希望提供的更简单,更不通用,这意味着编码并不难:

  • 在OS X上,有一个命令open可以完全按照您的要求执行:"open命令打开一个文件(或目录或URL),就像双击文件的图标一样." 所以,你可以popen open /Applications/MyGame.app.
  • 在Windows上,等效命令是start,但遗憾的是,它是cmd.exeshell 的一部分而不是独立程序.幸运的是,Python附带了一个os.startfile同样功能的函数,所以只是os.startfile(r'C:\Program Files\MyGame\MyGame.exe').
  • 在FreeDesktop兼容的*nix系统(包括大多数现代Linux发行版等)上,有一个非常相似的命令叫做xdg-open:"xdg-open在用户首选的应用程序中打开一个文件或URL." 再一次,只是popen xdg-open /usr/local/bin/mygame.
  • 如果您希望在其他平台上运行,则需要进行一些研究以找到最佳等效项.否则,对于Mac和Windows以外的任何东西,我只是尝试popen xdg-open,如果失败则抛出错误.

有关(未经测试的)示例,请参见http://pastebin.com/XVp46f7X.

请注意,这只能运行实际上可以双击以在Finder/Explorer/Nautilus/etc中启动的内容.例如,如果您尝试启动"./script.py",则根据您的设置,它可能会启动带有脚本的文本编辑器.

此外,在OS X上,您希望运行.app包,而不是其中的UNIX可执行文件.(在某些情况下,启动UNIX可执行文件 - 无论是在.app包中还是在独立包中 - 都可以工作,但不要依赖它.)

另外,请记住,以这种方式启动程序与从命令行运行程序不同 - 特别是,它将从Windows/Launch Services/GNOME/KDE /继承其环境,当前目录/驱动器等.等等 会话,而不是您的终端会话.如果您需要更多的控制孩子的过程,你需要看的文件open,xdg-open以及os.startfile和/或想出不同的解决方案.

最后,仅仅因为open/ xdg-open/ os.startfile成功并不意味着游戏正常启动.例如,如果它启动然后崩溃甚至可以创建一个窗口,它仍然看起来像你成功.

您可能希望查看PyPI以查找满足您需求的库.http://pypi.python.org/pypi/desktop看起来像是一种可能性.

或者您可以查看问题3177中的补丁,然后选择您最喜欢的补丁.据我所知,它们都是纯Python,您可以轻松地将添加的功能放在您自己的模块中,而不是在osshutil.

作为一个快速黑客,你可以(ab)使用webbrowser.open."请注意,在某些平台上,尝试使用此函数打开文件名,可能会起作用并启动操作系统的相关程序.但是,这既不支持也不可移植." 特别是IIRC,它不适用于OS X 10.5+.但是,我认为从文件名中创建文件:URL实际上是这样做的在OS X和Windows上工作,并且在大多数(但不是全部)配置上也适用于Linux.如果是这样,它可能足够快速和脏脚本.请记住,它没有记录工作,它可能会破坏你的一些用户,它可能会在未来中断,并且它被Python开发人员明确地视为滥用,所以我不会指望任何更严重的用户.并且它会在启动'script.py'或'Foo.app/Contents/MacOS/foo',传递env变量等时遇到同样的问题,作为上面更正确的方法.

几乎你问题中的其他一切都是无关紧要和错误的:

这通常不是问题,但程序是游戏,并且内置了Python解释器.

那没关系.如果游戏是从C代码写入stdout的话,它会做同样的事情.

当我使用subprocess.Popen时,它启动单独的程序,但在原始程序的Python实例下执行此操作

不,不.它启动了一个全新的过程,其嵌入式Python解释器是一个全新的Python实例.您可以通过例如运行与游戏嵌入不同的Python版本来验证.

这样他们就可以共享第一个Python控制台了.

不,他们没有.它们可能共享相同的tty/cmd窗口,但这不是一回事.

我可以很好地结束第一个程序,但我宁愿有单独的控制台(主要是因为我有隐藏的控制台启动,但是当我使用subprocess.POpen从Python启动程序时会显示它).

您可以随时将子项的stdout和stderr传递给日志文件,如果您愿意,可以将其与父进程的输出分开查看.但我认为这与你真正关心的事情无关.

此外,os.system将无法工作,因为我的目标是跨平台兼容性,而且只能在Windows上使用.

错误; os.system可以在"Unix,Windows"上找到 - 这可能是你关心的任何地方.但是,它不起作用,因为它使用相同的tty在脚本的子shell中运行子程序.(并且它还有很多其他问题 - 例如,阻止直到孩子完成.)