Продвинутые темы

17. Продвинутые темы #

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


17.1. Метаклассы #

Метаклассы управляют созданием классов. Они позволяют изменять или добавлять поведение на уровне классов.

Как работают метаклассы #

  1. Класс создается функцией type().
  2. Метакласс можно задать через параметр metaclass.
Пример: контроль за созданием атрибутов #
class Meta(type):
    def __new__(cls, name, bases, dct):
        if "required_method" not in dct:
            raise TypeError(f"Класс {name} должен содержать метод required_method")
        return super().__new__(cls, name, bases, dct)

class Base(metaclass=Meta):
    def required_method(self):
        pass  # Обязательный метод

# Класс без метода вызовет ошибку
# class InvalidClass(Base):
#     pass  # TypeError: Класс InvalidClass должен содержать метод required_method
Пример: автоматическое добавление атрибутов #
class AutoAttributes(type):
    def __new__(cls, name, bases, dct):
        dct["auto_attribute"] = "Добавлено метаклассом"
        return super().__new__(cls, name, bases, dct)

class MyClass(metaclass=AutoAttributes):
    pass

print(MyClass.auto_attribute)  # "Добавлено метаклассом"

17.2. Декораторы и контекстные менеджеры #

Декораторы #

Декораторы — функции, изменяющие или дополняющие поведение других функций или классов.

Пример: логирование вызовов функций #
def logger(func):
    def wrapper(*args, **kwargs):
        print(f"Вызов функции {func.__name__} с аргументами {args}, {kwargs}")
        return func(*args, **kwargs)
    return wrapper

@logger
def add(a, b):
    return a + b

print(add(2, 3))
Пример: декоратор с параметрами #
def repeat(n):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for _ in range(n):
                func(*args, **kwargs)
        return wrapper
    return decorator

@repeat(3)
def greet():
    print("Привет!")

greet()

Контекстные менеджеры #

Контекстные менеджеры управляют ресурсами, обеспечивая их автоматическое освобождение.

Пример: создание собственного контекстного менеджера #
class Resource:
    def __enter__(self):
        print("Ресурс открыт")
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        print("Ресурс закрыт")

with Resource() as res:
    print("Работа с ресурсом")
Контекстный менеджер с contextlib #
from contextlib import contextmanager

@contextmanager
def custom_context():
    print("Входим в контекст")
    yield
    print("Выходим из контекста")

with custom_context():
    print("Работа внутри контекста")

17.3. Работа с C-расширениями #

C-расширения используются для повышения производительности или интеграции с существующими библиотеками на C.

Модуль ctypes #

Позволяет вызывать функции из библиотек на C.

Пример: вызов функции из стандартной библиотеки #
import ctypes

libc = ctypes.CDLL("libc.so.6")
libc.printf(b"Привет из C!\n")

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

Cython компилирует Python-код в C, обеспечивая ускорение.

Установка #
pip install cython
Пример: ускорение Python-функции #
  1. Создайте файл example.pyx:
    def add(int a, int b):
        return a + b
    
  2. Создайте файл setup.py:
    from setuptools import setup
    from Cython.Build import cythonize
    
    setup(
        ext_modules=cythonize("example.pyx")
    )
    
  3. Скомпилируйте модуль:
    python setup.py build_ext --inplace
    
  4. Используйте:
    from example import add
    print(add(2, 3))  # 5
    

Создание расширения на C #

  1. Напишите файл example.c:
    #include <Python.h>
    
    static PyObject* say_hello(PyObject* self, PyObject* args) {
        return Py_BuildValue("s", "Привет из C!");
    }
    
    static PyMethodDef methods[] = {
        {"say_hello", say_hello, METH_NOARGS, "Приветствие"},
        {NULL, NULL, 0, NULL}
    };
    
    static struct PyModuleDef module = {
        PyModuleDef_HEAD_INIT, "example", NULL, -1, methods
    };
    
    PyMODINIT_FUNC PyInit_example(void) {
        return PyModule_Create(&module);
    }
    
  2. Скомпилируйте:
    gcc -shared -o example.so -I/usr/include/python3.8 -fPIC example.c
    
  3. Используйте:
    import example
    print(example.say_hello())
    

Рекомендации #

  • Используйте метаклассы для реализации сложных шаблонов проектирования.
  • Декораторы и контекстные менеджеры упрощают управление ресурсами и добавляют функциональность.
  • Для повышения производительности изучите Cython и модуль ctypes.