当前位置: 首页 > 面试题库 >

从Python启动另一个程序>分别地<

江展
2023-03-14
问题内容

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

如果我可以完全独立地启动第二个程序,就好象我只是“双击它”一样,我就想这样做。另外,由于我的目标是跨平台兼容性,所以os.system也不起作用,并且仅在Windows上可用。


问题答案:

如果我可以完全独立地启动第二个程序,就像我只是“双击它”一样,我会很喜欢。

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

幸运的是,与shutil.open最终希望提供的内容相比,您要尝试的操作更简单,更通用,这意味着编写代码并不难:

  • 在OS X上,有一个名为的命令open可以完全满足您的要求:“打开命令会打开一个文件(或目录或URL),就像您双击该文件的图标一样。” 因此,您可以popen open /Applications/MyGame.app
  • 在Windows上,等效命令为start,但不幸的是,它是cmd.exe外壳程序的一部分,而不是独立程序。幸运的是,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
/继承其环境,当前目录/驱动器等。等等 会话,而不是您的终端会话。如果您需要更多的控制孩子的过程,你需要看的文件openxdg- open以及os.startfile和/或想出不同的解决方案。

最后,只是因为open/ xdg- open/os.startfile成功,实际上并不意味着游戏启动正常。例如,如果启动后崩溃甚至无法创建窗口,那么对您来说仍然看起来像成功。

您可能需要查看PyPI来查找所需功能的库。http://pypi.python.org/pypi/desktop看起来很可能。

或者,您可以浏览3177期中的补丁,然后选择最喜欢的补丁。据我所知,它们都是纯Python,您可以轻松地将添加的函数放在自己的模块中,而不是inos或中shutil

作为一种快速技巧,您可能可以(滥用)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在脚本的子外壳中运行子程序。(这还有很多其他问题,例如阻塞直到孩子完成。)



 类似资料:
  • 问题内容: 我需要从另一个“容器”类启动一个Javafx应用程序,并在该应用程序上调用函数,但是似乎没有任何方法可以使用Application.launch()方法来获取对该应用程序的引用。这可能吗?谢谢 问题答案: 我遇到了同样的问题,并使用此hack解决了这个问题: 然后是您要从中启动应用程序的类: 希望对您有帮助。

  • 我们有一个公开REST API的现有java应用程序。当它收到超文本传输协议请求时,它使用Runtime.getRuntime(). exe启动另一个java进程。 我们正在将此应用程序迁移到docker,我们希望将这些服务、一个容器中的REST应用程序和另一个容器中的其他组件分开。 有没有办法,REST应用程序可以在另一个docker容器中启动另一个应用程序?

  • 问题内容: 我有一个GUI应用程序,需要在后台静默运行并继续收集信息。它首先需要显示UI以输入凭据,然后偶尔显示错误。 我了解我无法将GUI应用程序作为服务运行,因此我想创建服务只是为了启动GUI应用程序。因此,第一个程序作为服务运行,它仅启动GUI应用程序,然后继续监听来自GUI应用程序的任何信息。以下是启动GUI应用程序的第一个应用程序的代码。 当我运行此程序时,将启动GUI应用程序,但在5-

  • 我的想法是,我启动一个异步任务,从Tweeter获取状态...在这里之前一切正常...但是当我遇到一些特定的tweets时,我需要用服务器上的一些信息来修改它们,这里我将进行另一个网络操作,因为我需要等待,直到我从服务器上获取信息,我做: 这是从doInBackground()方法中的allready启动的AsyncTask启动的... 我知道我可以在AsyncTask中添加方法并在doInBac

  • 问题内容: 我遇到的问题是MainActivity中的onCreate()方法似乎无法启动另一个活动。 我的代码在工作,因此当我单击按钮时,“ AboutActivity”将启动。但是,我要这样做,以便MainActivity中的onCreate()完成后立即启动“ AboutActivity”。 尝试从onCreate()启动“ AboutActivity”时运行该程序时,该程序陷入了空白屏幕。

  • 我在使ActivityRecognitation服务保持运行时遇到问题。我目前有一个在后台连续运行的服务(GService)。我希望在GService中启动ActivityRecognitation服务,并让ActivityRecognitation服务将活动结果广播回GService。我能够启动服务并接收它正在运行的反馈,我还从意图处理程序获得一个结果(没有实际数据),但再也不会得到了。 以下是

  • 我试图通过按cardview开始另一项活动,cardview有一个朋友查找id。但是当我写回家时。java它给了我setOnClickListener中的问题。在homeActivity中,它告诉我无法解析“homeActivity”中的方法“homeActivity”。因为

  • 问题内容: 我有两个单独的节点应用程序。我希望其中一个能够在代码中的某个时刻启动另一个。我将如何去做? 问题答案: 使用。它与相似,但是用于创建V8的全新实例。因此,它专门用于运行Node的新实例。如果您只是执行命令,请使用或。 请注意,默认情况下使用时,流与父级关联。这意味着所有输出和错误都将在父进程中显示。如果您不希望与父级共享流,则可以在选项中定义属性: 然后,您可以将流程与主流程的流分开处