Evgenii Legotckoi
Evgenii LegotckoiШілде 18, 2018, 3:14 Т.Ж.

Өзіңіздің Python байланыстыруларыңызды жазыңыз

Бүгін біз өзіңіздің жобаңызға байланыстыруларды қалай жасауға болатынын қарастырамыз.

Qt компаниясы Python-ға арналған Qt құрамына сіздің негізгі байланыстыру құралы Shiboken де кіретінін қуана хабарлайды.

Төмендегі материалды оқып шығыңыз және сіз қарапайым C++ кітапханасы үшін Python байланыстарын жасау туралы түсінік аласыз.

Бұл сізді өзіңіздің жеке кітапханаларыңызбен бірдей істеуге шақырады деп үміттенеміз.

Кез келген Qt жобасы сияқты, біз Shiboken туралы мақалаларды беруге қуаныштымыз, осылайша оның барлығына түсінікті жақсартамыз.

Кітапхана үлгісі

Бұл жазбаның негізгі мақсаты - Universe деп аталатын аздап мағынасыз пайдаланушы кітапханасын пайдалану. Ол екі сыныпты ұсынады: балмұздақ (балмұздақ) және жүк көлігі (жүк көлігі).


Балмұздақ дәмімен сипатталады, ал Жүк машинасы маңайдағы балаларға балмұздақ жеткізу құралы ретінде қызмет етеді. Өте қарапайым.

Біз бұл сыныптарды Python ішінде пайдаланғымыз келеді. Қолданылатын жағдай қосымша балмұздақ дәмін қосу немесе балмұздақ жеткізудің сәтті болғанын тексеру болып табылады. Қарапайым тілмен айтқанда, біз балмұздақ пен жүк көлігіне арналған Python байланыстыруларын ұсынғымыз келеді, осылайша біз оларды Python сценарийінде пайдалана аламыз.

Біз қысқаша болу үшін кейбір бөліктерді өткізіп жібереміз, бірақ сіз толық бастапқы кодты алу үшін репозиторийді тексере аласыз. Репозиторийге сілтеме pyside-setup/examples/samplebinding .

C++ кітапханасы

Алдымен, Icecream тақырып файлын қарастырайық

class Icecream
{
public:
    Icecream(const std::string &flavor);
    virtual Icecream *clone();
    virtual ~Icecream();
    virtual const std::string getFlavor();

private:
    std::string m_flavor;
};

және жүк көлігі тақырыбы файлы

class Truck {
public:
    Truck(bool leaveOnDestruction = false);
    Truck(const Truck &other);
    Truck& operator=(const Truck &other);
    ~Truck();

    void addIcecreamFlavor(Icecream *icecream);
    void printAvailableFlavors() const;

    bool deliver() const;
    void arrive() const;
    void leave() const;

    void setLeaveOnDestruction(bool value);
    void setArrivalMessage(const std::string &message);

private:
    void clearFlavors();

    bool m_leaveOnDestruction = false;
    std::string m_arrivalMessage = "A new icecream truck has arrived!\n";
    std::vector m_flavors;
};

Көптеген API интерфейстерін түсіну оңай болуы керек, бірақ біз маңызды бөліктерді қорытындылаймыз:

  • Балмұздақ полиморфты түрі болып табылады және оны қайта анықтауға арналған
  • getFlavor() нақты алынған түрге байланысты дәмді қайтарады
  • Жүк көлігі өзіне тиесілі балмұздақ нысандарының векторын сақтайды, оны addIcecreamFlavor() арқылы қосуға болады.
  • Жүк көлігінің келуі туралы хабарды setArrivalMessage() арқылы конфигурациялауға болады.
  • deliver() бізге «балмұздақпен» жеткізу сәтті болды ма, жоқ па дейді

Шибокен типті жүйе

Shiboken-ті API туралы хабардар ету үшін бізге байланыстырулар қажет, ол үшін бізді қызықтыратын түрлерді қамтитын тақырып файлын жасаймыз:

#ifndef BINDINGS_H
#define BINDINGS_H
#include "icecream.h"
#include "truck.h"
#endif // BINDINGS_H

Сонымен қатар, shiboken C++ және Python түрлері арасындағы байланысты анықтайтын XML типтік жүйе файлын қажет етеді:

<?xml version="1.0"?>
<typesystem package="Universe">
    <primitive-type name="bool"/>
    <primitive-type name="std::string"/>
    <object-type name="Icecream">
        <modify-function signature="clone()">
            <modify-argument index="0">
                <define-ownership owner="c++"/>
            </modify-argument>
        </modify-function>
    </object-type>
    <value-type name="Truck">
        <modify-function signature="addIcecreamFlavor(Icecream*)">
            <modify-argument index="1">
                <define-ownership owner="c++"/>
            </modify-argument>
        </modify-function>
    </value-type>
</typesystem>

Бірінші назар аударатын маңызды нәрсе, біз «bool» және «std::string» қарабайыр типтер ретінде жариялаймыз. Кейбір C++ әдістері оларды параметр/қайтару түрлері ретінде пайдаланады, сондықтан шибокен олар туралы білуі керек. Содан кейін ол C++ және Python арасында сәйкес түрлендіру кодын жасай алады.

C++ қарабайыр түрлерінің көпшілігі шибокен арқылы ешқандай қосымша кодты қажет етпестен өңделеді. Содан кейін біз жоғарыдағы екі сыныпты жариялаймыз. Олардың бірі «объект-тип» (объект-тип), екіншісі «мән түрі» (құндылық-объект) ретінде.

Негізгі айырмашылығы, «нысан түрі» құрылған кодта көрсеткіш ретінде беріледі, ал «мән түрі» көшіріледі (мән семантикасы).

Жүйе түрінің файлында сынып атауларын орнату арқылы shiboken автоматты түрде сыныптарда жарияланған барлық әдістер үшін байланыстыруларды жасауға әрекет жасайды, сондықтан барлық әдіс атауларын қолмен көрсетудің қажеті жоқ...

Мүмкіндікті қандай да бір жолмен өзгерткіңіз келмесе, бұл бізді келесі тақырыпқа, Иелік ережелеріне әкеледі.

Шибокен Python кодында орналастырылған C++ нысандарын босатуға кім жауапты екенін сиқырлы түрде таба алмайды.

Көптеген жағдайлар болуы мүмкін: Python нысанына сілтемелер саны нөлге тең болғанда Python C++ жадын босатуы керек немесе Python C++ нысанын C++ кітапханасының бір нүктесінде жойылады деп есептей отырып, ешқашан жоймауы керек. Немесе бұл басқа нысанның ата-анасы болуы мүмкін (мысалы, QWidgets сияқты). Біздің жағдайда clone() әдісі тек C++ кітапханасының ішінде шақырылады және біз C++ коды клондалған нысанның жадын босатуға қамқорлық жасайды деп есептейміз.

addIcecreamFlavor() функциясына келетін болсақ, біз Жүк машинасының Icecream нысанында тұратынын және Жүк көлігі жойылғаннан кейін бірден жойылатынын білеміз. Сонымен, иелік «c++» болып орнатылды.

Егер біз иелік ережелерін көрсетпесек, сәйкес Python атаулары қолданыс аясынан шыққанда C++ нысандары жойылатын еді.

Ассамблея

Теңшелетін Universe кітапханасын құру және одан кейін ол үшін байланыстыруларды жасау үшін біз жақсы құжатталған, негізінен жалпы CMakeLists.txt файлын береміз, оны өз кітапханаларыңыз үшін қайта пайдалануға болады.

Ол негізінен жобаны орнату үшін «cmake.» деп қоңырау шалумен аяқталады, содан кейін таңдаған құралдар тізбегімен құрастырыңыз («(N) Makefiles генераторын ұсынамыз).

Жобаны жасау нәтижесінде сіз екі ортақ кітапхана аласыз: libuniverse. (so/dylib/dll) және Әлем. (so/pyd).

Біріншісі - теңшелетін C++ кітапханасы және соңғысы Python сценарийінен импортталатын Python модулі (құжат, сынақ драйвері).

Әрине, shiboken арқылы жасалған аралық файлдар да бар (Python байланыстарын жасау үшін жасалған .h/.cpp файлдары). Ақаулықтарды жоюдың қажеті болмаса немесе қандай да бір себептермен ол компиляцияланбаған болса немесе қажетінше әрекет етпесе, олар туралы алаңдамаңыз. Содан кейін сіз Qt компаниясына қате туралы есеп бере аласыз!

Соңында біз Python бөлігіне жетеміз.

Python модулін пайдалану

Келесі шағын сценарийде біз Universe модулін қолданамыз, Icecream-тен мұра аламыз, виртуалды әдістерді енгіземіз, нысандарды жасаймыз және т.б.

from Universe import Icecream, Truck

class VanillaChocolateIcecream(Icecream):
    def __init__(self, flavor=""):
        super(VanillaChocolateIcecream, self).__init__(flavor)

    def clone(self):
        return VanillaChocolateIcecream(self.getFlavor())

    def getFlavor(self):
        return "vanilla sprinked with chocolate"

class VanillaChocolateCherryIcecream(VanillaChocolateIcecream):
    def __init__(self, flavor=""):
        super(VanillaChocolateIcecream, self).__init__(flavor)

    def clone(self):
        return VanillaChocolateCherryIcecream(self.getFlavor())

    def getFlavor(self):
        base_flavor = super(VanillaChocolateCherryIcecream, self).getFlavor()
        return base_flavor + " and a cherry"

if __name__ == '__main__':
    leave_on_destruction = True
    truck = Truck(leave_on_destruction)

    flavors = ["vanilla", "chocolate", "strawberry"]
    for f in flavors:
        icecream = Icecream(f)
        truck.addIcecreamFlavor(icecream)

    truck.addIcecreamFlavor(VanillaChocolateIcecream())
    truck.addIcecreamFlavor(VanillaChocolateCherryIcecream())

    truck.arrive()
    truck.printAvailableFlavors()
    result = truck.deliver()

    if result:
        print("All the kids got some icecream!")
    else:
        print("Aww, someone didn't get the flavor they wanted...")

    if not result:
        special_truck = Truck(truck)
        del truck

        print("")
        special_truck.setArrivalMessage("A new SPECIAL icecream truck has arrived!\n")
        special_truck.arrive()
        special_truck.addIcecreamFlavor(Icecream("SPECIAL *magical* icecream"))
        special_truck.printAvailableFlavors()
        special_truck.deliver()
        print("Now everyone got the flavor they wanted!")
        special_truck.leave()

Модульден сыныптарды импорттағаннан кейін біз дәмдерімен теңшелген екі туынды (екінші) балмұздақ түрін жасаймыз.

Содан кейін біз жүк көлігін (жүк машинасын) жасаймыз, оған балмұздақтың (балмұздақтың) бірнеше қарапайым нұсқаларын (сорттарын) және екі арнайы нұсқаларды қосамыз.

Біз балмұздақ (балмұздақ) жіберуге (жеткізуге) тырысамыз.

Егер жеткізу сәтсіз болса, біз ескі нұсқалары көшірілген жаңа жүк көлігін және барлық тұтынушыларды қанағаттандыратын жаңа сиқырлы нұсқасын жасаймыз.

Жоғарыдағы сценарий C++ түріндегі қорытындыны пайдалануды, виртуалды әдістерді қайта анықтауды, нысандарды жасауды және жоюды және т.б. қысқаша көрсетеді.

Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.

Ол саған ұнайды ма? Әлеуметтік желілерде бөлісіңіз!

Пікірлер

Тек рұқсаты бар пайдаланушылар ғана пікір қалдыра алады.
Кіріңіз немесе Тіркеліңіз
OI
  • Ora Iro
  • Жел. 24, 2024, 6:38 Т.Ж.

C++ - Тест 001. Первая программа и типы данных

  • Нәтиже:40ұпай,
  • Бағалау ұпайлары-8
AD

C++ - Тест 004. Указатели, Массивы и Циклы

  • Нәтиже:50ұпай,
  • Бағалау ұпайлары-4
m
  • molni99
  • Қаз. 26, 2024, 1:37 Т.Ж.

C++ - Тест 004. Указатели, Массивы и Циклы

  • Нәтиже:80ұпай,
  • Бағалау ұпайлары4
Соңғы пікірлер
ИМ
Игорь МаксимовҚар. 22, 2024, 11:51 Т.Ж.
Django - Оқулық 017. Теңшелген Django кіру беті Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
Evgenii Legotckoi
Evgenii LegotckoiҚаз. 31, 2024, 2:37 Т.Қ.
Django - Сабақ 064. Python Markdown кеңейтімін қалай жазуға болады Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
A
ALO1ZEҚаз. 19, 2024, 8:19 Т.Ж.
Qt Creator көмегімен fb3 файл оқу құралы Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
ИМ
Игорь МаксимовҚаз. 5, 2024, 7:51 Т.Ж.
Django - Сабақ 064. Python Markdown кеңейтімін қалай жазуға болады Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
d
dblas5Шілде 5, 2024, 11:02 Т.Ж.
QML - Сабақ 016. SQLite деректер қоры және онымен QML Qt-та жұмыс істеу Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
Енді форумда талқылаңыз
Evgenii Legotckoi
Evgenii LegotckoiМаусым 24, 2024, 3:11 Т.Қ.
добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
t
tonypeachey1Қар. 15, 2024, 6:04 Т.Ж.
google domain [url=https://google.com/]domain[/url] domain [http://www.example.com link title]
NSProject
NSProjectМаусым 4, 2022, 3:49 Т.Ж.
Всё ещё разбираюсь с кешем. В следствии прочтения данной статьи. Я принял для себя решение сделать кеширование свойств менеджера модели LikeDislike. И так как установка evileg_core для меня не была возможна, ибо он писался…
9
9AnonimҚаз. 25, 2024, 9:10 Т.Ж.
Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…

Бізді әлеуметтік желілерде бақылаңыз