← Назад к вопросам

Можно ли написать функции для Python?

1.3 Junior🔥 101 комментариев
#Python Core#Архитектура и паттерны

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Написание расширений для Python на C/C++

Да, абсолютно! Python позволяет писать высокопроизводительные функции и модули на C/C++, встраивая их в Python код. Это критически важно для оптимизации узких мест программы.

Зачем писать расширения на C?

Проблема:

# Python медленный для computationally intensive работ
def slow_function(n):
    result = 0
    for i in range(n):
        result += i ** 2
    return result

import time
start = time.time()
slow_function(100_000_000)  # ~10 секунд
print(f"Time: {time.time() - start}")

Решение: Написать эту функцию на C — будет в 10-100 раз быстрее!

Способ 1: CPython API (нативное расширение)

// myextension.c
#include <Python.h>

// C функция
static long sum_of_squares(long n) {
    long result = 0;
    for (long i = 0; i < n; i++) {
        result += i * i;
    }
    return result;
}

// Python wrapper
static PyObject* py_sum_of_squares(PyObject* self, PyObject* args) {
    long n;
    if (!PyArg_ParseTuple(args, "l", &n)) {
        return NULL;
    }
    long result = sum_of_squares(n);
    return PyLong_FromLong(result);
}

// Таблица методов
static PyMethodDef Methods[] = {
    {"sum_of_squares", py_sum_of_squares, METH_VARARGS, "Calculate sum of squares"},
    {NULL, NULL, 0, NULL}
};

// Определение модуля
static struct PyModuleDef mymodule = {
    PyModuleDef_HEAD_INIT,
    "myextension",
    "C extension example",
    -1,
    Methods
};

// Инициализация
PyMODINIT_FUNC PyInit_myextension(void) {
    return PyModule_Create(&mymodule);
}

setup.py:

from setuptools import setup, Extension

module = Extension(
    "myextension",
    sources=["myextension.c"]
)

setup(
    name="myextension",
    ext_modules=[module]
)

Использование:

import myextension
import time

start = time.time()
result = myextension.sum_of_squares(100_000_000)
print(f"Result: {result}")
print(f"Time: {time.time() - start}")  # ~0.1 секунды!

Способ 2: ctypes (FFI для готовых библиотек)

Если есть скомпилированная C библиотека:

// math_lib.c
long sum_of_squares(long n) {
    long result = 0;
    for (long i = 0; i < n; i++) {
        result += i * i;
    }
    return result;
}

Компиляция:

gcc -shared -fPIC math_lib.c -o libmath.so  # Linux
gcc -shared math_lib.c -o libmath.dylib    # macOS

Python код:

import ctypes
import os

# Загрузка библиотеки
lib_path = os.path.dirname(__file__) + "/libmath.so"
lib = ctypes.CDLL(lib_path)

# Определение функции
sum_of_squares = lib.sum_of_squares
sum_of_squares.argtypes = [ctypes.c_long]
sum_of_squares.restype = ctypes.c_long

# Использование
result = sum_of_squares(100_000_000)
print(f"Result: {result}")  # Очень быстро!

Способ 3: cffi (удобнее ctypes)

# Определение интерфейса
from cffi import FFI

ffi = FFI()

# Объявляем C функцию
ffi.cdef("""
    long sum_of_squares(long n);
""")

# Компилируем
ffi.set_source(
    "_math_lib",
    """
    long sum_of_squares(long n) {
        long result = 0;
        for (long i = 0; i < n; i++) {
            result += i * i;
        }
        return result;
    }
    """
)
ffi.compile(verbose=True)

# Использование
from _math_lib import lib
result = lib.sum_of_squares(100_000_000)
print(result)

Способ 4: Cython (Python → C автоматически)

Cython позволяет писать на похожем на Python синтаксисе, который компилируется в C.

# math_fast.pyx
# -*- cython: language_level=3 -*-

def sum_of_squares(long n):
    """Очень быстрая версия на Cython"""
    cdef long result = 0
    cdef long i
    for i in range(n):
        result += i * i
    return result

setup.py:

from setuptools import setup
from Cython.Build import cythonize

setup(
    ext_modules=cythonize("math_fast.pyx")
)

Использование — как обычный Python модуль:

import math_fast

result = math_fast.sum_of_squares(100_000_000)
print(result)  # Очень быстро!

Сравнение производительности

import time
import math_fast  # Cython версия

def pure_python(n):
    result = 0
    for i in range(n):
        result += i * i
    return result

n = 100_000_000

# Чистый Python
start = time.time()
pure_python(n)
print(f"Pure Python: {time.time() - start:.2f}s")  # ~10 сек

# Cython
start = time.time()
math_fast.sum_of_squares(n)
print(f"Cython: {time.time() - start:.2f}s")  # ~0.1 сек (100x быстрее!)

Практические примеры в реальных проектах

NumPy и Pandas — написаны на C, обёрнуты в Python:

import numpy as np

arr = np.array([1, 2, 3, 4, 5])
result = np.sum(arr)  # Это вызывает C код!  Очень быстро

Cryptography модули:

from cryptography.hazmat.primitives import hashes

# Под капотом — высокопроизводительный C код из OpenSSL
digest = hashes.Hash(hashes.SHA256())
digest.update(b"data")
result = digest.finalize()

PostgreSQL адаптер psycopg2:

import psycopg2

# Соединение и работа с БД очень быстра благодаря C расширениям
conn = psycopg2.connect("dbname=mydb")
cur = conn.cursor()
cur.execute("SELECT * FROM users")  # Быстрая работа с большими данными

Когда писать расширения

Да, пишите расширение если:

  • Функция вызывается миллионы раз в секунду
  • Узкое место — не I/O, а computation
  • Есть готовая C/C++ библиотека

Нет, не пишите если:

  • Код работает достаточно быстро
  • Узкое место — сетевые запросы
  • Есть готовое оптимизированное решение (NumPy)

Вывод

Python позволяет писать расширения на C/C++ несколькими способами: CPython API (мощно, но сложно), ctypes (для готовых библиотек), cffi (удобнее), Cython (ближе к Python). Это критично для оптимизации производительности в data-heavy приложениях и научных вычислениях.

Можно ли написать функции для Python? | PrepBro