HTML Diff
0 added 0 removed
Original 2026-01-01
Modified 2026-03-10
1 <p>Теги: python, с, компилятор, c api, cpython, компиляция, портируемость кода, reference management, cython, swig, binding, shared libraries, ctypes, cffi, pypy, .h, libffi</p>
1 <p>Теги: python, с, компилятор, c api, cpython, компиляция, портируемость кода, reference management, cython, swig, binding, shared libraries, ctypes, cffi, pypy, .h, libffi</p>
2 <p>Безусловно, Python хорош всем. Но иногда всё же хочется немножко побыстрее. Сначала совершаются попытки изменить алгоритмический подход. Но если и этого не хватает, то дело серьёзное, пора засучивать рукава и расчехлять С-компилятор.</p>
2 <p>Безусловно, Python хорош всем. Но иногда всё же хочется немножко побыстрее. Сначала совершаются попытки изменить алгоритмический подход. Но если и этого не хватает, то дело серьёзное, пора засучивать рукава и расчехлять С-компилятор.</p>
3 <p>Кстати говоря, эта необходимость не всегда бывает вызвана проблемами с производительностью. Иногда просто нужно вызывать какой-нибудь C-функционал из Python, чтобы, например, протестировать его. Есть разные варианты скрещивания Python и С в зависимости от навыков и потребностей.</p>
3 <p>Кстати говоря, эта необходимость не всегда бывает вызвана проблемами с производительностью. Иногда просто нужно вызывать какой-нибудь C-функционал из Python, чтобы, например, протестировать его. Есть разные варианты скрещивания Python и С в зависимости от навыков и потребностей.</p>
4 <h2>Рассмотрим три способа</h2>
4 <h2>Рассмотрим три способа</h2>
5 <ul><li>Непосредственно писать на С, связываясь с Python через<strong>C API</strong>, который предоставляет<strong>CPython</strong>. Это путь для тех, кто неплохо владеет С и хочет иметь практически полный контроль над тем, что происходит. Но это возлагает на программиста ответственность за компиляцию,<strong>портируемость кода</strong>и даже за<strong>reference management</strong>объектов интерпретатора.</li>
5 <ul><li>Непосредственно писать на С, связываясь с Python через<strong>C API</strong>, который предоставляет<strong>CPython</strong>. Это путь для тех, кто неплохо владеет С и хочет иметь практически полный контроль над тем, что происходит. Но это возлагает на программиста ответственность за компиляцию,<strong>портируемость кода</strong>и даже за<strong>reference management</strong>объектов интерпретатора.</li>
6 <li>Писать код, который транслируется в C. Обычно в данном случае подразумевает использование<strong>Cython</strong>. Любой Python-код = уже валидный<strong>Cython</strong>-код!<strong>Cython</strong>сгенерит (особенно с помощью аннотаций, за написание которых уже отвечает программист) С-код, по возможности применив различные оптимизации и обеспечив портируемость. Минусы тут следуют из плюсов: опять нужно компилировать, нужно учить новый синтаксис и инструменты. Есть еще<strong>SWIG</strong>, но он скорее полезен для тех случаев, когда есть необходимость сделать много<strong>binding</strong>’ов к одному С-коду.</li>
6 <li>Писать код, который транслируется в C. Обычно в данном случае подразумевает использование<strong>Cython</strong>. Любой Python-код = уже валидный<strong>Cython</strong>-код!<strong>Cython</strong>сгенерит (особенно с помощью аннотаций, за написание которых уже отвечает программист) С-код, по возможности применив различные оптимизации и обеспечив портируемость. Минусы тут следуют из плюсов: опять нужно компилировать, нужно учить новый синтаксис и инструменты. Есть еще<strong>SWIG</strong>, но он скорее полезен для тех случаев, когда есть необходимость сделать много<strong>binding</strong>’ов к одному С-коду.</li>
7 <li>Писать код, который вызывает С-функции из разделяемых библиотек (<strong>shared libraries</strong>). Здесь многое зависит от того, насколько<em>"развесистый"</em>интерфейс необходимо вызывать. Для небольших вполне подходит<strong>ctypes</strong>- встроенного в<strong>CPython</strong>механизма. Проблема лишь в том, что описание вызываемых функций, передаваемых типов, кастинг и пр. - всё это крайне подвержено ошибкам. Да и читается это тяжело. Поэтому для сложных интерфейсов лучше подойдет<strong>cffi</strong>от создателей<strong>Pypy</strong>. Этой библиотеке не нужно всё объяснять, она сама многое выяснит, взглянув на<strong>.h</strong>-файл. Оба инструмента работают за счёт<strong>libffi</strong>, которая позволяет получить знание "как вызвать С-функцию", грубо говоря, объединив символы из разделяемой библиотеки и описание из<strong>.h</strong>-файла.</li>
7 <li>Писать код, который вызывает С-функции из разделяемых библиотек (<strong>shared libraries</strong>). Здесь многое зависит от того, насколько<em>"развесистый"</em>интерфейс необходимо вызывать. Для небольших вполне подходит<strong>ctypes</strong>- встроенного в<strong>CPython</strong>механизма. Проблема лишь в том, что описание вызываемых функций, передаваемых типов, кастинг и пр. - всё это крайне подвержено ошибкам. Да и читается это тяжело. Поэтому для сложных интерфейсов лучше подойдет<strong>cffi</strong>от создателей<strong>Pypy</strong>. Этой библиотеке не нужно всё объяснять, она сама многое выяснит, взглянув на<strong>.h</strong>-файл. Оба инструмента работают за счёт<strong>libffi</strong>, которая позволяет получить знание "как вызвать С-функцию", грубо говоря, объединив символы из разделяемой библиотеки и описание из<strong>.h</strong>-файла.</li>
8 </ul><p><em>Есть вопрос? Напишите в комментариях!</em></p>
8 </ul><p><em>Есть вопрос? Напишите в комментариях!</em></p>
9  
9