Рубрики
Без рубрики

Различия между файлами Python .pyc, .pyd и .pyo

Автор оригинала: Tendai Mutunhire.

В этой статье мы рассмотрим типы файлов Python .pyc , .pyo и .pyd , а также то, как они используются для хранения байт-кода, который будет импортирован другими программами Python.

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

Байт-код и виртуальная машина Python

Python поставляется с интерпретатором, который может использоваться в качестве REPL (read-eval-print-loop) в интерактивном режиме в командной строке. Кроме того, вы можете вызвать Python со скриптами кода Python. В обоих случаях интерпретатор анализирует ваши входные данные и затем компилирует их в байт-код (машинные инструкции более низкого уровня), который затем выполняется “питоническим представлением” компьютера. Это питоновское представление называется виртуальной машиной Python .

Однако он настолько отличается от других виртуальных машин, таких как виртуальная машина Java или виртуальная машина Erlang, что заслуживает собственного изучения. Виртуальная машина, в свою очередь, взаимодействует с операционной системой и реальным оборудованием для выполнения собственных машинных инструкций.

Важно иметь в виду, когда вы видите типы файлов .pyc,. pyo и .pyd, что это файлы, созданные интерпретатором Python, когда он преобразует код в скомпилированный байт-код. Компиляция исходного кода Python в байт-код является необходимым промежуточным этапом в процессе перевода инструкций из исходного кода на удобочитаемом языке в машинные инструкции, которые может выполнять ваша операционная система.

В этой статье мы рассмотрим каждый тип файла отдельно, но сначала мы предоставим краткую информацию о виртуальной машине Python и байт-коде Python.

Тип файла .pyc

Сначала рассмотрим тип файла .pyc. Файлы типа .pyc автоматически генерируются интерпретатором при импорте модуля, что ускоряет дальнейший импорт этого модуля. Поэтому эти файлы создаются только из файла .py, если он импортирован другим файлом .py или модулем.

Вот пример модуля Python, который мы хотим импортировать. Этот модуль вычисляет факториалы.

# math_helpers.py

# a function that computes the nth factorial, e.g. factorial(2)
def factorial(n):
    if n == 0:
        return 1
    else:
        return n * factorial(n - 1)

# a main function that uses our factorial function defined above
def main():
    print("I am the factorial helper")
    print("you can call factorial(number) where number is any integer")
    print("for example, calling factorial(5) gives the result:")
    print(factorial(5))

# this runs when the script is called from the command line
if __name__ == '__main__':
    main()

Теперь, когда вы просто запускаете этот модуль из командной строки, используя python math_helpers.py , файлы. pyc не создаются.

Теперь давайте импортируем это в другой модуль, как показано ниже. Мы импортируем функцию factorial из math_helpers.py файл и использование его для вычисления факториала 6.

# computations.py

# import from the math_helpers module
from math_helpers import factorial

# a function that makes use of the imported function
def main():
    print("Python can compute things easily from the REPL")
    print("for example, just write : 4 * 5")
    print("and you get: 20.")
    print("Computing things is easier when you use helpers")
    print("Here we use the factorial helper to find the factorial of 6")
    print(factorial(6))

# this runs when the script is called from the command line
if __name__ == '__main__':
    main()

Мы можем запустить этот скрипт, вызвав python computations.py на терминале. Мы не только получаем результат 6 факториалов, то есть 720, но и замечаем, что интерпретатор автоматически создает файл math_helpers.pyc . Это происходит потому, что модуль computations импортирует модуль math_helpers . Чтобы ускорить загрузку импортируемого модуля в будущем, интерпретатор создает файл байт-кода модуля.

Когда файл исходного кода обновляется, файл .pyc также обновляется. Это происходит всякий раз, когда время обновления исходного кода отличается от времени обновления файла байт-кода и гарантирует, что байт-код обновлен.

Обратите внимание, что использование файлов .pyc ускоряет только загрузку вашей программы, а не ее фактическое выполнение. Это означает, что вы можете улучшить время запуска, написав свою основную программу в модуле, который импортируется другим, меньшим модулем. Однако для повышения производительности в более общем плане вам необходимо изучить такие методы, как оптимизация алгоритмов и алгоритмический анализ.

Поскольку файлы .pyc не зависят от платформы, они могут совместно использоваться на машинах с различными архитектурами. Однако, если разработчики имеют разные часы в своих системах, проверка файлов .pyc в системе управления версиями может создать временные метки, которые в будущем будут эффективно использоваться для других показаний времени. Таким образом, обновления исходного кода больше не вызывают изменений в байт-коде. Это может быть неприятная ошибка, чтобы обнаружить. Лучший способ избежать этого-добавить файлы .pyc в список игнорирования в вашей системе управления версиями.

Тип файла .pyo

Тип файла .pyo также создается интерпретатором при импорте модуля . Однако файл .pyo является результатом запуска интерпретатора при включенных настройках оптимизации.

Оптимизатор включается путем добавления флага “-O” при вызове интерпретатора Python. Вот пример кода, иллюстрирующий использование оптимизации. Во-первых, у нас есть модуль, который определяет лямбду. В Python лямбда – это то же самое, что и функция, но она определяется более лаконично.

# lambdas.py

# a lambda that returns double whatever number we pass it
g = lambda x: x * 2

Если вы помните из предыдущего примера, нам нужно будет импортировать этот модуль, чтобы использовать его. В следующем списке кодов мы импортируем lambdas.py и использовать g лямбда.

# using_lambdas.py

# import the lambdas module
import lambdas

# a main function in which we compute the double of 7
def main():
    print(lambdas.g(7))

# this executes when the module is invoked as a script at the command line
if __name__ == '__main__':
    main()

Теперь мы подходим к критической части этого примера. Вместо обычного вызова Python, как в предыдущем примере, мы будем использовать оптимизацию здесь. При включенном оптимизаторе создаются файлы байт-кода меньшего размера, чем при отсутствии оптимизатора.

Чтобы запустить этот пример с помощью оптимизатора, вызовите команду:

$ python -O using_lambdas.py

Мы не только получаем правильный результат удвоения 7, то есть 14, в качестве вывода в командной строке, но и видим, что для нас автоматически создается новый файл байт-кода. Этот файл основан на импорте lambdas.py в вызове using_lambdas.py . Поскольку у нас был включен оптимизатор, создается файл байт-кода .pyo. В этом случае он называется lambdas.pyo .

Оптимизатор, который делает не так уж много, удаляет операторы assert из вашего байт-кода. В большинстве случаев результат не будет заметен, но могут быть моменты, когда он вам понадобится.

Также обратите внимание, что, поскольку файл байт-кода .pyo создается, он заменяет файл .pyc, который был бы создан без оптимизации. При обновлении файла исходного кода файл .pyo обновляется всякий раз, когда время обновления исходного кода отличается от времени обновления файла байт-кода.

Тип файла .pyd

Тип файла .pyd, в отличие от двух предыдущих, является специфичным для платформы класса операционных систем Windows. Таким образом, он может часто встречаться в персональных и корпоративных выпусках Windows 10, 8, 7 и других.

В экосистеме Windows файл .pyd-это файл библиотеки, содержащий код Python, который может быть вызван и использован другими приложениями Python. Чтобы сделать эту библиотеку доступной для других программ Python, она упакована как динамическая библиотека ссылок.

Динамические библиотеки ссылок (DLL) – это библиотеки кода Windows, которые связаны с вызывающими программами во время выполнения . Основное преимущество ссылок на библиотеки во время выполнения, такие как библиотеки DLL, заключается в том, что они облегчают повторное использование кода, модульную архитектуру и более быстрый запуск программы. В результате библиотеки DLL предоставляют множество функциональных возможностей в операционных системах Windows.

Файл .pyd-это динамическая библиотека ссылок, содержащая модуль Python или набор модулей, вызываемых другим кодом Python. Чтобы создать файл .pyd, вам нужно создать модуль с именем, например, example.pyd . В этом модуле вам нужно будет создать функцию с именем PyInit_example() . Когда программы вызывают эту библиотеку, им нужно вызвать import foo , и будет запущена функция PyInit_example () .

Для получения дополнительной информации о создании собственных файлов Python .pyd ознакомьтесь с этой статьей .

Различия Между Этими Типами Файлов

Хотя между этими типами файлов существует некоторое сходство, есть и некоторые большие различия. Например, хотя файлы .pyc и .pyo похожи тем, что содержат байт-код Python, они отличаются тем, что файлы .pyo более компактны благодаря оптимизации, выполненной интерпретатором.

Третий тип файлов,. pyd, отличается от двух предыдущих тем, что является динамически связанной библиотекой, используемой в операционной системе Windows. Два других типа файлов можно использовать в любой операционной системе, а не только в Windows.

Однако каждый из этих типов файлов включает код, который вызывается и используется другими программами Python.

Вывод

В этой статье мы описали, как каждый специальный тип файла,. pyc,. pyo и .pyd, используется виртуальной машиной Python для повторного использования кода. Каждый файл, как мы видели, имеет свои особые цели и варианты использования, будь то ускорение загрузки модуля, ускорение выполнения или облегчение повторного использования кода в определенных операционных системах.