{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Modules et packages" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Les modules et les packages permettent d'ajouter des fonctionnalités à Python\n", "\n", "Un module est un fichier (```.py```) qui contient des fonctions et/ou des classes. \n", "Et de la documentation bien sûr\n", "\n", "Un package est un répertoire contenant des modules et des sous-répertoires.\n", "\n", "C'est aussi simple que ça. Évidemment en rentrant dans le détail c'est un peu plus compliqué." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Un module" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%%file operations.py\n", "\n", "# -*- coding: utf-8 -*-\n", "\n", "\"\"\"\n", "Module pour le cours sur les modules\n", "Opérations arithmétiques\n", "\"\"\"\n", "\n", "def addition(a, b):\n", " \"\"\" Ben une addition quoi : a + b \"\"\"\n", " return a + b\n", "\n", "def soustraction(a, b):\n", " \"\"\" Une soustraction : a - b \"\"\"\n", " return a - b" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Pour l'utiliser on peut :\n", "* l'importer par son nom" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import operations\n", "operations.addition(2, 4)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* l'importer et modifier son nom" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import operations as op\n", "op.addition(2, 4)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* importer une partie du module" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from operations import addition\n", "addition(2, 4)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* importer l'intégralité du module" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from operations import *\n", "addition(2, 4)\n", "soustraction(4, 2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "En réalité seules les fonctions et/ou les classes ne commençant pas par '_' sont importées. \n", "L'utilisation de ``import *`` n'est pas recommandée. Parce que, comme vous le savez « *explicit is better than implicit* ». Et en ajoutant les fonctions dans l'espace de nommage du script vous pouvez écraser des fonctions existantes. \n", "Ajoutez une fonction ``print`` à votre module pour voir (attention un module n'est chargé qu'une fois, vous devrez relancer le kernel ou passer par la console)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Autre définition d'un module : c'est un objet de type ``module``." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import operations\n", "type(operations)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "``import`` ajoute des attributs au module" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import operations\n", "\n", "print(\"name : {}\".format(operations.__name__))\n", "print(\"file : {}\".format(operations.__file__))\n", "print(\"doc : {}\".format(operations.__doc__))\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Un package" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "! tree operations_pack" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Un package python peut contenir des modules, des répertoires et sous-répertoires, et bien souvent du non-python : de la doc html, des données pour les tests, etc…\n", "\n", "Le répertoire principal et les répertoires contenant des modules python doivent contenir un fichier ``__init__.py`` \n", "``__init__.py`` peut être vide, contenir du code d'initialisation ou contenir la variable ``__all__``\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import operations_pack.simple\n", "operations_pack.simple.addition(2, 4)\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from operations_pack import simple\n", "simple.soustraction(4, 2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "``__all__`` dans ``__init__.py`` définit quels seront les modules qui seront importés avec ``import *``\n" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "8" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from operations_pack.avance import *\n", "multi.multiplication(2,4)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Où sont les modules et les packages ?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Pour que ``import`` fonctionne il faut que les modules soient dans le PATH." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['',\n", " '/usr/lib/python36.zip',\n", " '/usr/lib/python3.6',\n", " '/usr/lib/python3.6/lib-dynload',\n", " '/home/clement/.local/lib/python3.6/site-packages',\n", " '/usr/local/lib/python3.6/dist-packages',\n", " '/usr/lib/python3/dist-packages',\n", " '/usr/local/lib/python3.6/dist-packages/IPython/extensions',\n", " '/home/clement/.ipython']" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import sys\n", "sys.path" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "``sys.path`` est une liste, vous pouvez la modifier" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['',\n", " '/usr/lib/python36.zip',\n", " '/usr/lib/python3.6',\n", " '/usr/lib/python3.6/lib-dynload',\n", " '/home/clement/.local/lib/python3.6/site-packages',\n", " '/usr/local/lib/python3.6/dist-packages',\n", " '/usr/lib/python3/dist-packages',\n", " '/usr/local/lib/python3.6/dist-packages/IPython/extensions',\n", " '/home/clement/.ipython',\n", " '/tmp/modules']" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sys.path.append(\"/tmp/modules\")\n", "sys.path" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Installer des modules et des packages" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Dans les distributions Python récentes ``pip`` est installé, tant mieux.\n", "\n", "Avec ``pip`` vous pouvez :\n", "* installer un module ``pip install module`` ou ``pip install --user module``\n", "``pip`` va trouver le module sur Pypi et l'installer au bon endroit s'il existe. Il installera les dépendances aussi.\n", "* désinstaller un module ``pip uninstall module``\n", "* mettre à jour ``pip install module --upgrade``\n", "* downgrader dans une version particulière ``pip install module=0.9 --upgrade``\n", "* sauvegarder votre environnement de dév, la liste de vos modules ``pip freeze > requirements.txt`` \n", "Ce qui vous permettra de le réinstaller sur une autre machine ``pip install -r requirements.txt``\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## S'en sortir avec les versions" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Python évolue au fil des versions, les packages aussi. Ça peut poser des problèmes quand vous voulez partager votre code ou même quand vous voulez utiliser un code qui a besoin d'une version particulière.\n", "\n", "Il existe un outil pour isoler les environnement de développement : ``virtualenv`` \n", "``virtualenv /path/mon_projet`` ou ``python3 -m venv /path/mon_projet`` va créer un dossier avec plein de trucs dedans, y compris un interpréteur python. \n", "Vous pouvez spécifier la version de python avec ``virtualenv /path/mon_projet -p /usr/bin/python3.6``\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Pour activer l'environnement : ``source /path/mon_projet/bin/activate`` (``/path/mon_projet/Scripts/activate.bat`` sous Windows (je crois)) \n", "Pour en sortir : ``deactivate``" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Quand vous travaillez dans un venv les modules que vous installerez avec pip seront isolés dans le venv et pas ailleurs. \n", "Si vous utilisez ``python`` ce sera la version de l'interpréteur du venv et les modules du venv. \n", "Avec cet outil on doit installer à chaque fois les modules désirés mais au moins on ne s'embrouille pas. Et vous pouvez communiquer un fichier ``requirements.txt`` à un collègue qui pourra reproduire le venv sur sa machine." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Il existe aussi ``pipenv``, un outil plus récent qui combine ``pip`` et ``virtualenv``." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.4" } }, "nbformat": 4, "nbformat_minor": 2 }