Когда я должен использовать Python - git над подпроцессом - PullRequest
0 голосов
/ 02 мая 2020

Я пытаюсь убедить моего коллегу, что использование подпроцесса для получения головы репо - это плохо, потому что порождение подпроцесса или создание процесса сопряжено с большими издержками. Чтобы убедить его, я создал два сценария и профилировал их, но результаты оказались не такими, как я ожидал (python - git будет быстрее, чем подпроцесс).

Это первый сценарий - test_git_module.py который я профилировал

import git


def test():

    repo = git.Repo(".", search_parent_directories=True)

test()

После профилирования с помощью cProfile - python3 -m cProfile test_git_module -s я получил вывод 78059 function calls (75806 primitive calls) in 0.130 seconds

С другой стороны , когда я Профилированный скрипт test_subprocess.py вывод был 6529 function calls (6430 primitive calls) in 0.017 seconds

test_subprocess.py

import subprocess
import os
import sys


def test():

    SELF_DIRPATH = os.path.dirname(__file__)
    WORKSPACE_DIRPATH = (
        subprocess.run(["git", "rev-parse", "--show-toplevel"], stdout=subprocess.PIPE, check=True)
        .stdout.decode(sys.stdout.encoding)
        .strip()
    )

test()

Итак, ясно, что в этом python - git совсем не помогает, и это тот, который действительно медлителен для выполнения таких задач. Это подводит меня к вопросу, что когда и почему кто-то должен использовать Python - GIT над подпроцессом?

Ответы [ 2 ]

1 голос
/ 02 мая 2020

Использование subprocess имеет явные преимущества.

  • Модуль subprocess является частью стандартной библиотеки.
  • Это шаблон, с которым вы очень часто сталкиваетесь ; не каждая программа имеет модуль Python.
  • В современных (особенно UNIX -подобных) системах создание процесса происходит быстро и дешево.

Что касается синтаксического анализа output, с git log не так сложно сформировать вывод, который будет легко проанализирован;

git log --pretty=format:"%h%x09%an%x09%ad%x09%s"

(из этот ответ ). При этом каждый коммит создается как одна строка с поля, разделенные табуляцией символов; очень легко для преобразования;

import subprocess as sp

args = ['git', 'log', '--pretty=format:%h%x09%an%x09%ad%x09%s']
commits = [ln.split('\t') for ln in sp.check_output(args, text=True).splitlines()]

Конечно, есть другие программы, где обработка выходных данных сложнее. Однако;

  • Текст - это универсальный интерфейс.
  • Это Python! Преобразование и обработка данных составляет ядро ​​ языка.
0 голосов
/ 02 мая 2020

git модуль не был создан для скорости выполнения. Вызов команд оболочки и анализ выходных данных делает ваш код нечитаемым, сложным в обслуживании и иногда может быть сложным. Вызов python функций вместо subprocess.run чаще всего более элегантен, удобен для чтения и удобен.

git rev-parse --show-toplevel - это простой вывод для анализа. Как насчет git log? Я не говорю, что это невозможно, но 95% вашего кода будет касаться вызова shell и анализа вывода, а не логики c. Очевидно, что вы можете создать функцию для каждой команды, которая вам нужна, но это то, чем является модуль git.

Это как ORM против голых SQL запросов. Большинство разработчиков предпочитают ORM для удобства.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...