问题描述
我在Windows 10下运行Python 3.5,我正在使用matplotlib.pyplot
生成PGF文件,这是我用于LaTeX的图像。
我正在运行一个前端GUI,它提供最终用户配置选项,然后调用matplotlib.pyplot.savefig()
来生成并保存图像。
我backend_pgf.py
的问题是matplotlib
后端使用( backend_pgf.py
)进行backend_pgf.py
subprocess.Popen()
调用,强制弹出Windows控制台窗口(cmd)以执行所需的LaTeX处理。
视觉上它会分散用户的注意力,应该隐藏起来。
这是代码片段:
latex = subprocess.Popen([str(self.texcommand), "-halt-on-error"],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
cwd=self.tmpdir)
我想要做的是阻止显示控制台窗口。
我知道我可以使用subprocess.STARTUPINFO()来设置dwFlags并阻止显示该控制台窗口(或传入shell=True
)。
我可以覆盖有问题的类,但该类嵌套在其他类和模块中,因此您可以想象管理代码库的复杂性,以便进行简单的函数更改。
我的问题是...... 如何在像 matplotlib?
这样的逻辑深度包中进行此更改 matplotlib?
非常感谢。
丰富
1楼
如果您完全控制正在编写的应用程序,并且在任何时候都不希望终端窗口(我假设您没有),您可以使用猴子补丁子进程.Popen调用自身以始终设置该标志。
它相对无痛 - 只需在你的app的初始化代码中调用这样的函数:
def patch():
import subprocess
original_popen = subprocess.Popen
def Popen(*args, **kwargs):
# code to create your STARTUPINFO object
kwargs["startupinfo"] = subprocess # ...
return original_open(*args, **kwargs)
subprocess.Popen = Popen
无论是在matplotlib内部深度嵌套都不改变调用 - 只要在matplotlib本身初始化之前调用此函数,即使这样,只有matplotlib中的模块可以from subprocess import Popen
才会失败(因此它将独立引用原始的Popen)。
但如果发生这种情况,那就更好了:只需在matplotlib子模块中修补Popen名称即可。
2楼
对于像这样的问题,这些变化对于库的常规功能而言是无关紧要的,我经常只是修补有问题的函数/方法。 在你的情况下,它会是这样的
from matplotlib.backends.backend_pgf import LatexManager
def __init_patched__(self):
# copy/paste the original source here and make your changes
LatexManager.__init__ = __init_patched__
当然,如果matplotlib源更改,您将需要更新修补的代码