Использование низкоуровневого модуля расширения Python

ispolzovanie nizkourovnevogo modulya rasshireniya python Интеграция Python/C

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

Пример 20.20. PP4E\Integrate\Extend\Swig\Shadow\main_low.py

выполняет те же тесты, что и main.cxx и main.py, но использует низкоуровневый интерфейс функций доступа на C from _number import * # модуль-обертка расширения c++

num = new_Number(1)

Number_add(num, 4) # явная передача указателя ‘this’

Number_display(num) # использовать функции доступа в модуле на C

Number_sub(num, 2)

Number_display(num)

print(Number_square(num))

Number_data_set(num, 99) print(Number_data_get(num)) Number_display(num) print(num)

delete_Number(num)

Этот сценарий порождает по сути такой же вывод, как main.py; но так как сценарий был несколько упрощен, то экземпляр класса C++ в данном случае является более низкоуровневым объектом, чем теневой класс.

/PP4E/Integrate/Extend/Swig/Shadow$ python main_low.py

Number: 1

add 4

Number=5 sub 2 Number=3 9 99

Number=99

_6025aa00_p_Number ~Number: 99

Наследование классов C++ в подклассах Python

Как видите, модули расширений вполне возможно использовать напрямую, но здесь не видно преимуществ перехода от использования теневого класса к использованию функций. При использовании теневого класса вы одновременно получаете основанный на объектах интерфейс к C++ и доступный для наследования объект Python. Так, модуль Python, представленный в примере 20.21, расширяет класс C++, добавляя в метод add вызов функции print и определяя новый метод mul. Так как теневой класс — это класс Python, все это действует естественным образом.

Пример 20.21. PP4E\Integrate\Extend\Swig\Shadow\main_subclass.py

"подкласс класса C++ в Python (подкласс сгенерированного теневого класса)"

from number import Number # импортировать теневой класс

class MyNumber(Number):

def add(self, other): # расширить метод print(‘in Python add…’) Number.add(self, other)

def mul(self, other): # добавить новый метод print(‘in Python mul…’) self.data = self.data * other

num = MyNumber(1) # те же тесты, что и в main.cxx, main.py

num.add(4) # использовать подкласс Python теневого класса

num.display() # add() — специализированная в Python версия

num.sub(2) num.display() print(num.square())

num.data = 99 print(num.data) num.display()

num.mul(2) # mul() — реализован на языке Python

num.display() print(num) # repr из теневого суперкласса

del num

Теперь метод add выводит дополнительные сообщения, а метод mul автоматически изменяет член data класса C++ при присваивании self.data — программный код на языке Python расширяет программный код на языке C++:

…/PP4E/Integrate/Extend/Swig/Shadow$ python main_subclass.py Number: 1

in Python add… add 4

Number=5

sub 2

Number=3

9

99

Number=99

in Python mul… Number=198

>  __main__.MyNumber; proxy of <Swig Object of type ‘Number *’ at 0x7ff4baa0> > ~Number: 198

Иными словами, SWIG упрощает использование библиотек классов C++ в качестве базовых классов в сценариях Python. Среди всего прочего, эта возможность позволяет использовать существующие библиотеки классов C++ в сценариях Python и оптимизировать их, программируя отдельные фрагменты иерархии классов на C++, когда это необходимо. Практически то же самое можно делать, создавая типы на C, поскольку в настоящее время типы являются классами (и наоборот), но процедура обертывания классов C++ с помощью SWIG часто оказывается существенно проще.

Использованная литература:

Марк Лутц — Программирование на Python, 4-е издание, II том, 2011

Каталог сайтов Всего.ру
Оцените статью
Секреты программирования
Добавить комментарий