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
Пример 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