Tutoriel Python : comment créer un module

Table des matières 

Introduction

  1. Créer un module en Python
  2. Importer un module en Python
  3. Les propriétés d’un module en python
  4. Exercices
  5. Correction des exercices
  6. Conclusion

Introduction

Chaque fois que vous quittez et réintroduisez, l'interpréteur Python, les définitions que vous avez créés (fonctions et variables) se perdent. Par conséquent, si vous souhaitez développer un code un peu plus longtemps, il est préférable d'utiliser un éditeur de texte pour planifier l'entrée de l'interpréteur et l'exécuter avec ce fichier en entrée, inversement.

C'est ce qu’on appelle la formalisation de script. Au cours du développement du logiciel, il est possible que vous souhaitiez le décomposer en différents fichiers afin de simplifier la maintenance. Vous pourrez également utiliser une fonction pratique que vous avez écrite dans de nombreux autres programmes sans avoir à reproduire sa définition à l'intérieur de chaque programme. Pour vous aider, Python a la possibilité de mettre des définitions dans un fichier et de les utiliser dans le code de l'interpréteur ou dans des instances interactives, ce même fichier est considéré comme un module ; 

Un module est un fichier qui contient des définitions et des instructions de Python.  Le nom du fichier est le nom du module avec le suffixe .py attaché. Le nom du module (uniquement sous forme de chaîne) de chaque module est disponible sous la forme y inclut sa variable globale __name__.

1. Créer un module en Python 

Dans cet exemplaire, vous commencez par créer un module simple et conventionnel basé sur des entrées de nombres entiers. Vous créez ensuite un autre module qui définit une classe pouvant être utilisée pour représenter des données binaires et qui expose des fonctions binaires en tant que méthodes. Enfin, vous créez un paquet contenant les deux modules.

A. Créez un nouveau dossier appelé bitwise. Celui-ci devient éventuellement votre paquet.

B. Dans ce dossier, créez un script Python appelé bits.py contenant le code suivant :

Syntaxe:

'''
Les entrées sont des valeurs entières et les types de retour sont des entiers de 16 bits ou des booléens.
Les indices de bits sont basés sur des zéros
Les fonctions implémentées sont :
NOT(int) -> int
AND (int, int) -> int
OR (int, int) -> int
XOR (int, int) -> int
shiftleft (int, num) -> int
shiftright (int, num) -> int
bit(int, index) -> bool
setbit(int, index) -> int
zerobit(int,index) -> int
listbits(int,num) -> [int,int...,int]
'''
def NOT(value):
return ~value
def AND(val1,val2):
return val1 & val2
def OR(val1, val2):
return val1 | val2
def XOR(val1,val2):
return val1^val2
def shiftleft(val, num):
return val def shiftright(val, num):
return val >> num
def bit(val,idx):
mask = 1 return bool(val & 1)
def setbit(val,idx):
mask = 1 return val | mask
def zerobit(val, idx):
mask = ~(1 return val & mask
def listbits(val):
num = len(bin(val)) - 2
result = []
for n in range(num):
result.append( 1 if bit(val,n) else 0 )
return list( reversed(result) )

C. Enregistrez le fichier et, tout en restant dans votre dossier bitwise, lancez le programme Python.

D. Tapez le code suivant pour tester votre nouveau module :

Exemple1 :

Syntaxe:

import bits
bits.NOT(0b0101)
bin(bits.NOT(0b0101))
bin(bits.NOT(0b0101) & 0xF)
bin(bits.AND(0b0101, 0b0011) & 0xF)
bin(bits.AND(0b0101, 0b0100) & 0xF)
bin(bits.OR(0b0101, 0b0100) & 0xF)
bin(bits.OR(0b0101, 0b0011) & 0xF)
bin(bits.XOR(0b0101, 0b11) & 0xF)
bin(bits.XOR(0b0101, 0b0101) & 0xF)
bin(bits.shiftleft(0b10,1)
bin(bits.shiftleft(0b10,4))
bin(bits.shiftright(0b1000,2))
bin(bits.shiftright(0b1000,6)
bits.bit(0b0101,0)
bits.bit(0b0101,1)
bin(bits.setbit(0b1000,1))
bin(bits.zerobit(0b1000,1))
bits.listbits(0b10111)

Résultat d’exécution :

L'essai du module donne lieu à quelques questions intéressantes. Vous commencez par importer votre nouveau module(bits.py). Comme vous êtes dans le dossier où se trouve le fichier, Python peut le voir sans modifier la valeur du sys.path.Vous commencez à tester avec la fonction NOT() (préfixée, bien sûr, par le nom du module, les bits), et tout de suite vous pouvez voir une anomalie dans le fait que l'interpréteur Python affiche la représentation décimale comme résultat.

Pour résoudre ce problème, vous pouvez utiliser la fonction bin() pour convertir le nombre en une représentation sous la forme d'une chaîne binaire. Cependant, il y a toujours un problème car le nombre est négatif. Cela est dû au fait que les entiers Python sont signés, c'est-à-dire qu'ils peuvent représenter des nombres positifs ou négatifs. 

Python effectue cela en interne en faisant en sorte que le bit à l’extrémité gauche représente le signe. Lorsque vous inversez tous les bits, vous inversez également le signe ! Vous pouvez éviter la confusion en utilisant un bitmask de 0xF (ou un décimal 15 si vous préférez) pour ne récupérer que les 4 bits à l’extrémité droite. En convertissant cela avec bin (), vous voyez maintenant le schéma de bits inversé que vous attendiez. Évidemment, si la valeur que vous inversiez était supérieure à 16, vous devriez utiliser un bitmask plus long. Rappelez-vous simplement que chaque chiffre hexadécimal est de 4 bits, donc tout ce que vous avez à faire est d'ajouter un F supplémentaire à votre mask.

La prochaine étape de tests - allant de la fonction AND() à shiftleft() - devrait être simple, et vous pouvez vérifier les résultats en inspectant visuellement les modèles de bits d'entrée et les résultats. Les exemples de shiftright() montrent un résultat intéressant, à savoir que le fait de déplacer les bits trop loin à droite produit un résultat nul. En d'autres termes, Python remplit l'espace "vide" laissé par le décalage des opérations avec des zéros.

Pour passer à la nouvelle fonctionnalité, vous avez utilisé bit(), setbit() et zerobit() pour tester et modifier des bits individuels dans la valeur donnée. De même, vous pouvez inspecter visuellement les modèles d'entrée et de résultat pour veiller à ce que les résultats soient corrects. Rappelez-vous que le paramètre index commence à zéro et que de la droite. Enfin, vous avez testé la fonction listbits(). Une fois de plus, vous pouvez facilement comparer l'entrée binaire avec la liste de numéros qui en résulte.

Exemple 2 :

Nous allons suivre les mêmes pistes pour ce module(fibo.py) :

Syntaxe:

# Module de Fibonacci
def fib(n): # écrire la série de Fibonacci de 0 jusqu'à n
a, b = 0, 1
while a print(a, end=' ')
a, b = b, a+b
print()
def fib2(n): # retourner la série de Fibonacci à n
result = []
a, b = 0, 1
while a result.append(a)
a, b = b, a+b
return result

Syntaxe:

import fibo
fibo.fib(100)
fibo.fib2(50)

Résultat d’exécution :

2. Importer un module en Python 

Vous accédez aux modules en utilisant le mot-clé import, qui a de nombreuses variantes en Python. Les formes les plus courantes sont présentées ici :

Syntaxe:

import a_Module
import aModule as an_Alias
import first_Module, second_Module, third_Module...
from a_Module import anObject
from a_Module import an_Object as an_Alias
from a_Module import first_Object,second_Object, third_Object...
from a_Module import *

Le dernier format importe tous les noms visibles de a_Module dans l'espace de noms actuels. (Vous apprendrez bientôt à contrôler la visibilité.) Cela comporte un risque important de créer des conflits de noms avec des noms intégrés ou des noms que vous avez définis, ou que vous définirez, localement. Il est donc recommandé de n'utiliser que le dernier format d'importation pour tester les modules à l'invite Python.

Les autres formats de... sont beaucoup plus sécurisants, car vous n'importez que des noms spécifiques et, si nécessaire, vous les renommez avec un alias. Cela rend les conflits avec d'autres noms locaux beaucoup moins probables.

Lorsque vous importez un module en utilisant l'un des trois premiers formats, vous pouvez accéder à son contenu en préfixant le nom requis par le nom du module (ou alias) en utilisant la notation par points. Par exemple, sys.path est un attribut du module sys.

Exemple 3 :

Python fournit une vaste bibliothèque de modules, à titre d'exemple :

Syntaxe:

import utils
print(utils.__name__)
print(utils.__doc__)
print(utils.__file__)
print(dir(utils))

Généralement, les modules ne sont que des fichiers sources. En pratique, vous devez observer les choses à faire et à éviter pour créer des modules. Vous devez éviter le code de haut niveau qui sera exécuté lors de l'importation du module, sauf, éventuellement, pour une certaine initialisation des variables qui peut dépendre de l'environnement local. Cela signifie que le code que vous souhaitez réutiliser doit être conditionné sous forme de fonction ou de classe. Il est également courant de fournir une fonction de test qui exerce toutes les fonctions et classes du module. Les noms des modules sont aussi traditionnellement en minuscules.

3. Les propriétés d’un module en python :

Chaque module a un ensemble de propriétés qui peuvent être utilisées pour trouver les fonctionnalités fournies, le nom, la chaîne de documentation, etc. Ces propriétés sont considérées comme spéciales car elles commencent et se terminent toutes par une double barre inférieure ('__'). Ceux-ci sont :

  • __name__ : le nom du module.
  • __doc__  : la documentation  pour le module.
  • __file__  : le fichier dans lequel le module a été défini.

Vous pouvez également obtenir une liste du contenu d'un module une fois qu'il a été importé en utilisant la fonction dir ().

Exemple 4 :

Syntaxe:

import utils
print(utils.__name__)
print(utils.__doc__)
print(utils.__file__)
print(dir(utils))

Résultat d’execution :

Notez que l'instruction d'impression(print) est toujours exécutée car elle est exécutée lorsque le module est chargé dans le runtime actuel de Python ; même si tout ce que nous faisons alors accéder à certaines propriétés du module.

La plupart des propriétés de module sont utilisées par des outils pour aider les développeurs ; mais ils peuvent être des références utiles lorsque vous rencontrez pour la première fois un nouveau module.

4. Exercices :

 Exercice 1 : Importer le module de maths et appeler les fonctions sin et tan

Exercice 2 : créer un module (fons.py) avec les fonctions arithmétiques de base (addition, division, multiplication, soustraction).

Exercice 3 : Importer le module fons.py est tester les fonctions implémentées.

Exercice 4 : créer un tableau à 2 dimensions à l'aide du module des tableaux

Exercice 5 : écrire un programme en python pour choisir un caractère aléatoire dans une chaîne donnée.

5. Correction des exercices :

Exercice 1 :

Syntaxe:

import math
math.degrees(math.sin(45))
math.degrees(math.tan(45))

Résultat de l’exécution :

Exercice 2 :

Syntaxe:

#fon.py
def addition(x, y):
return x + y
def division(x, y):
return x / y
def multiplication (x, y):
return x * y
def soustraction(x, y):
return x - y

Résultat d’exécution :

Enregistrez le fichier fons.py dans votre machine.

Exercice 3 :

Syntaxe:

import fons
print(fons.addition(12.1, 8))
print(fons.soustraction(10.34, 5.1))
print(fons.division(4, 7))
print(fons.multiplication(1.5, 6))

Résultat d’exécution :

Exercice 4 :

Syntaxe:

#importer Numpy module
import numpy as np
a=np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])
print("a: ",a)

Résultat d’exécution :

Exercice 5 :

Syntaxe:

#importer random module
import random
chaine = 'cour-gratuit'
char = random.choice(chaine)
print("le caractère aléatoire est ", char)

Résultat d’exécution :

6. Conclusion

La programmation modulaire est une façon d'organiser le code source de votre programme. Par organisation de votre code en modules (fichiers sources Python) et en paquets (collections de modules), puis l'importation de ces modules et paquets dans votre programme, vous pouvez garder vos programmes organisés de façon logique et éviter les problèmes.

Au cours de la croissance et de l'évolution de votre programme, vous devrez souvent réécrire ou développer certaines parties de votre code. Les techniques de programmation modulaire permettent de gérer ces  modifications, en minimisant les effets secondaires et en gardant votre code sous contrôle.

En travaillant avec les techniques de programmation modulaire, vous apprendrez un certain nombre de modèles communs d'utilisation des modules et des paquets, comme l'approche "diviser pour mieux régner" de la programmation, l'utilisation de l'abstraction et de l'encapsulation, et l'idée d'écrire des modules extensibles.

Article publié le 07 Novembre 2020par Babachekhe Mohamed