.. _l-python_cplusplus: Python et C++, stratégies ========================= On n'utilise le `C/C++ `_ que dans le but d'accélérer un programme Python. Il existe plusieurs façons de mélanger les deux langages. .. contents:: :local: CPython +++++++ L'interpréteur `Python `_ a toujours été écrit en C. `CPython `_ est l'implémentation en C des modules standards autrefois écrits en Python. CPython est aussi une machine virtuelle comme l'est Java. Les programmes Python sont compilés sous forme `bytecode `_ (qu'il est possible d'analyser avec le module `dis `_) puis exécutés. .. index:: ctypes C++ et Python séparés avec ctypes +++++++++++++++++++++++++++++++++ Le module `ctypes `_ permet d'utiliser une `librairie `_ compilée séparément (`DLL `_ sous Windows). Le programme Python déclare les fonctions qu'il souhaite utiliser. Les interfaces sont souvent écrites en C. C'est l'option choisie par la librairie `XGBoost `_. La librairie C++ est compilée et expose des fonctions via une API C : `c_api.h `_. Une fois la compilation terminée, il faut recopier la librairie compilée (`instructions `_). Cette librairie est incluse dans le fichier `setup.py `_ lorsque celui-ci est *buildé*. Dans le code du package, la librairie est chargé via la fonction `_load_lib `_. Les méthodes de la DLL sont appelées comme elles le seraient dans un programme python. Exemple avec la fonction `XGDMatrixCreateFromFile `_. Il est préférable de connaître le C/C++ pour comprendre pourquoi les types Python et C sont différentes ou encore ce que veut `ctypes.byref `_. .. index:: cython C++ avec Cython +++++++++++++++ C'est l'option choisie par beaucoup de modules tels que `scikit-learn `_. C'est aussi la moins verbeuse et la plus accessible surtout qu'il possible de s'interface facilement avec `numpy `_. Les fichiers d'extension *pyd* déclarent les fonctions qui seront implémentées en Cythno. Ils sont optionnels. Les fichiers d'extensions *pyx* implémentent des fonctions en Cython. Exemple : `_utils.pyd `_ et `_utils.pyx `_. Ces fichiers sont toujours accompagnés d'instructions de compilation : `tree/setup.py `_ et `setup.py `_. * `tutoriel `_ * `Cython et Numpy `_ Cython permet aussi d'écrire du code en allégeant la contrainte sur le `GIL `_ ou *Global Interpreter Lock*. Celui-ci impose l'exécution du langage sur un seul thread. Il faut savoir ce qu'on fait quand on relâche cette contrainte mais c'est le seul moyen d'écrire un programme vraiment parallèle. * `cython.parallel `_ Le langage Python effectue constamment plein de vérifications comme le fait qu'un indice soit en dehors d'une liste. Cython permet d'écrire un code plus rapide mais moins sûr en esquivant ces contraintes : * `directives de compilation `_ Le plus simple pour commencer à se familiariser est d'utiliser la commande magique `%%cython `_ qui effectue les opérations de compilation pour le programmeur. .. index:: pybind11, boost_python, SWIG Modules Python écrits en C ++++++++++++++++++++++++++ Il faut lire le tutoriel `Extending Python with C or C++ `_. C'est la solution qui produit le code le plus efficace mais il faut constamment convertir des données depuis Python vers C et réciproquement. Il faut aussi gérer soi-même le `comptage des références `_ afin que le `garbage collector `_ garde la trace des objets créés et détruits. Cette option est devenue moins intéressente avec les récents développement de Python. Il faut citer deux outils qui permettent de faciliter l'habillage d'une librairie C en Python : * `SWIG `_ * `Boost Python `_ * `pybind11 `_ Compiler le langage Python ++++++++++++++++++++++++++ Le langage Python n'est pas compilable mais certains outils tentent de convertir un code existant en C/C++ pour le compiler ensuite. Un des problèmes rencontrés est l'`inférence de type `_ : la compilateur requiert la connaissance du type d'une variable et celui n'est connu qu'à l'exécution. Quelques outils : * `llvmlite `_ * `Nuitka `_ * `Numba `_ * `PyPy `_ * `Pyston `_ Tous repose sur un mécanisme appelé `JIT `_ ou *compilation à la volée*. .. index:: cpyquickhelper Un exemple ++++++++++ Le module `cpyquickhelper `_ implémente quelques façons de mettre du C dans un module :epkg:`Python` et contient toutes les instructions pour en faire un module compilé et prêt à l'emploi.