Tutoriel "Cython" pour rendre Python explosif: configuration de base

Aperçu

Je veux faire du code écrit en ** c ++ ** dans une ** bibliothèque ** qui peut être appelée par ** python **. Cependant, il y avait un grand mur appelé ** cython **.

Dépendances de bibliothèques sombres, construction d'un environnement qui vous donne envie de devenir fou. Conversion de type que je ne sais pas quoi faire. Ce sentiment de désespoir qui me fait me demander si j'écris en python, en c ++ ou ce que je fais.

J'ai un peu plus de temps pour toucher cython, alors j'aimerais le résumer petit à petit. Je suis un niveau débutant pour python, c ++ et cython, donc si vous avez des erreurs, faites-le moi savoir.

Contenu

Cette fois, je viserai à ** cythoniser et appeler ** à partir de python en tant que bibliothèque ** du code C ++ très simple.

La ** structure de dossier ** minimale est la suivante.

hoge@~/Documents/cython_test> tree .
.
├── cython
│   ├── library_cython.pyx
│   ├── test_library.pxd
│   └── test_library.pyx
├── my_library
│   ├── test.cpp
│   └── test.h
└── setup.py

2 directories, 6 files

setup.py Tout d'abord, setup.py était nécessaire pour créer la bibliothèque.

test_library``` est le nom de la bibliothèque à lire par python.

En d'autres termes, après la construction, appelez import test_library.

setup.py


from setuptools import setup, Extension, find_packages
from Cython.Build import cythonize
from Cython.Distutils import build_ext
from distutils import sysconfig

ext_modules = [
    Extension(
        "test_library", sources=[
            "./cython/test_library.pyx",
            "./my_library/test.cpp"
        ],
        language="c++"
    )
]

setup(
    name = "test_library",
    cmdclass = {"build_ext": build_ext},
    ext_modules= cythonize(ext_modules)
)

En ce moment,

    Extension(
        "test_library", sources=[
            "./cython/test_library.pyx",

setup(
    name = "test_library",

Gardons les noms des trois `` test_library '' qui apparaissent dans. J'étais accro ici.

Code côté c ++

Créez une classe appelée TestClass '' du côté c ++. Appelez cela depuis python via cython. Pour plus de simplicité, TestClass n'a qu'un constructeur et une méthode appelée test_function1 () ''. À ce stade, attachons correctement l'espace de noms. Je ne sais pas pourquoi, mais c'est plus pratique lors de la conversion en cython. Ici, l'espace de noms est my_library```.

test.h


namespace my_library
{
class TestClass{
    public:
        TestClass();
        void test_function1();
};    
} // namespace my_library


Écrivez le contenu de la fonction définie dans l'en-tête. test_function1 () '' `` est juste une fonction à imprimer.

test.cpp


#include <iostream>
#include "test.h"
using namespace std;

namespace my_library{

TestClass::TestClass(){};
void TestClass::test_function1(){
    cout << "printed from cpp function" << endl;
}


}

Code côté cython

Comme vous pouvez le voir dans setup.py, test_library.pyx est le fichier cython principal. Inclut `` `` library_cython.pyx ci-dessous.

test_library.pyx


import cython
cimport cython

include "library_cython.pyx"

def test():
    return TestClassCython()

Le fichier pxd``` est comme un fichier de définition pour transmettre les informations nécessaires à test_library.pyx depuis C ++. Maintenant, nous avons vraiment besoin de réécrire ce qui a été défini dans l'en-tête c ++ sous la forme de cython.

test_library.pxd


cdef extern from "../my_library/test.h" namespace "my_library":
    cdef cppclass TestClass:
        TestClass()
        void test_function1()

Dans cette `` bibliothèque_cython.pyx '', nous définirons la classe python (cython?) Qui est en fait appelée du côté python. Le premier casse-tête consiste à conserver le pointeur de la classe définie en c ++ comme variable membre de la classe. Le constructeur construit une classe côté c ++ et transmet son adresse à cette variable membre ptr. Le destructeur efface ce ptr avec del.

De plus, la méthode `test_function1_cython ()` appelle en interne la méthode définie côté c ++ en la définissant sur ptr.test_function1 () ``.

library_cython.pyx


import cython
cimport cython

cdef class TestClassCython:
    cdef TestClass* ptr

    def __cinit__(self):
        self.ptr = new TestClass()

    def __deadaloc(self):
        del self.ptr

    def test_function1_cython(self):
        self.ptr.test_function1()

Si vous pouvez le construire, félicitez-vous.

Lorsque ce qui précède est prêt,


python setup.py install

ça ira. Si vous construisez avec succès, entrez l'interpréteur python et


Python 3.6.7 (default, Nov 16 2019, 21:57:19) 
[GCC 4.2.1 Compatible Apple LLVM 10.0.0 (clang-1000.11.45.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import test_library
>>> a = test_library.test()
>>> a.test_function1_cython()
printed from cpp function
>>> 

Je serais heureux si je pouvais faire ça.

Résumé

Donc, en utilisant cython, j'ai essayé d'appeler une classe écrite en c ++ à partir de python via une bibliothèque. Ce n'est que le début, et les dépendances peuvent être déroutantes, par exemple lors de l'utilisation d'une bibliothèque qui doit être compilée avec c ++, mais j'aimerais réécrire pour un cas légèrement plus sombre.

Si vous le trouvez utile, nous nous réjouissons de vos goûts et commentaires! !!

fin.

Recommended Posts

Tutoriel "Cython" pour rendre Python explosif: configuration de base
Tutoriel "Cython" pour rendre Python explosif: Passez l'objet de classe C ++ à l'objet de classe côté Python. Partie 2
Tutoriel "Cython" qui rend Python explosif: lorsque le code C ++ dépend de la bibliothèque. Préparation
Tutoriel "Cython" pour rendre Python explosif: Passez un objet de classe C ++ à un objet de classe côté Python. Partie ①
Tutoriel "Cython" qui rend Python explosif: lorsque le code C ++ dépend de la bibliothèque. Écrivez setup.py.
Tutoriel "Cython" pour rendre Python explosif: Lorsqu'une fonction côté C ++ a une surcharge.
Tutoriel "Cython" pour rendre Python explosif: Comment analyser la classe Enum définie en code C ++ vers Enum en Python.
Tutoriel "Cython" qui rend Python explosif: lorsque le code C ++ dépend de la bibliothèque. Tout d'abord, CMake.
Tutoriel "Cython" qui rend Python explosif: Gérer le passage de fonctions côté C ++ par référence.
Comment créer un robot - Basic
[Tutoriel Python] Une introduction facile à Python
Conseils pour faciliter la lecture des documents d'audition Python
[Python] Comment rendre une classe itérable
Fractal pour faire et jouer avec Python
Tutoriel Python
J'ai essayé de toucher Python (syntaxe de base)
Je veux faire un jeu avec Python
Essayez de créer un code de "décryptage" en Python
Essayez de créer un groupe de dièdre avec Python
Comment créer le plugin Python de Substance Painter (Introduction)
Je veux créer du code C ++ à partir de code Python!
Comment rendre le Python des débutants plus rapide [numpy]
Comment apporter des modifications à l'interpréteur Python dans Pycharm
Explication de base de Lark (faites un gars comme une coquille avec Python, Lark)
[Introduction à Python] Utilisation de base des expressions lambda
Mis à jour vers Python 2.7.9
RF Python Basic_01
Tutoriel Python Django (5)
Tutoriel Python Django (2)
Résumé du didacticiel Python
Écriture de base Python
Grammaire de base Python3
RF Python Basic_02
Tutoriel Python Django (7)
Tutoriel Python Django (1)
Tutoriel du didacticiel Python Django
Tutoriel Python Django (3)
"Backport" vers python 2
Tutoriel Python Django (4)
Un outil pour créer des images de masque pour ETC en Python
python débutant essaie d'ajouter une authentification de base à l'administrateur de Django
Essayez de créer un module Python en langage C
Faisons un outil de veille de commande avec python
Expliquez en détail comment créer un son avec python
Suite ・ J'ai essayé de créer Slackbot après avoir étudié Python3
Lisez le fichier xml en vous référant au didacticiel Python
Comment créer un package Python à l'aide de VS Code
[Python] Je veux faire d'une liste imbriquée un taple
[Introduction à Python] Utilisation basique de la bibliothèque matplotlib