2017-02-09 10 views
1

Я запускаю Python 3.5 под Windows 10, и я использую matplotlib.pyplot для создания PGF-файлов, которые я использую для использования в LaTeX.Подпроцесс Python вызывает в Matplotlib на Windows

Я запускаю интерфейсный интерфейс пользователя, который предоставляет параметры конфигурации конечного пользователя, а затем совершает вызовы в matplotlib.pyplot.savefig(), который генерирует и сохраняет изображение.

У меня есть проблема в том, что matplotlib бэкенд используется (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?

Спасибо много.

Rich

ответ

0

Если вы находитесь в полном контроле над приложением вы пишете, и не хотите, в любой момент окна терминала (я предполагаю, что вы не), вы можете прибегнуть к обезьяне пропатчить subprocess.Popen вызвать себя, чтобы всегда устанавливать этот флаг.

Это относительно безболезненно - просто вызвать функцию, как это в коде инициализации для вашего приложения:

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). Но если это происходит, тем лучше: просто поместите имя Popen в подмодуль matplotlib.

+0

** Обучение весело. ** Спасибо за это. Я вообще не знал об исправлениях обезьян (концепция имеет смысл для динамических языков). Для тех, кто не знаком, подробнее см. [Обезьяна-исправление (ссылка SO)] (https://stackoverflow.com/questions/5626193/what-is-a-monkey-patch). Обратите внимание, что с любой хорошей концепцией к ней следует относиться с осторожностью. – richbl

0

Для таких проблем, когда изменения были бы несущественными для регулярного функционирования библиотеки, я часто просто обезумел исправление функции/метода нарушения. В вашем случае это будет что-то вроде этого

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 изменяет

+0

Спасибо. Я дал согласие на [jsbueno] (https://stackoverflow.com/users/108205/jsbueno), так как кажется, что он ответил перед вами, хотя вы оба пришли к такому же ответу.Я добавлю, что вы предприняли дополнительные усилия для правильной идентификации требуемого класса ('LatexManager'). Если бы я мог дать вам дополнительную оценку этой детали, я бы! – richbl

+0

В этом случае я считаю, что принятый ответ лучше, потому что он просто добавляет требуемый аргумент и полностью независим от источника matplotlib. Мой ответ более применим к общему случаю, когда патч не так прост, как добавление дополнительного аргумента функции. – user3419537

 Смежные вопросы

  • Нет связанных вопросов^_^