Importation de modules

Un module (aussi appelé bibliothèque) python est un ensemble de fonctions et de données qui provient d'un autre fichier. Nous avons importés plusieurs modules dans les exemples précédents, en particulier

Systématiquement, nous avons utilisé la commande qui permet d'importer le module en lui conservant un espace de nom séparé

import p5
import random

vitesseX =random.uniform(-5,5)

Dire que l'on a conservé un espace de nom séparé signifie qu'il faut systématiquement utiliser le nom du module en préfixe des fonctions que l'on utilise. On utilise par exemple random.uniform(-5,5) ou p5.run(). Cette façon de faire est très sécurisante. si par exemple un des modules que l'on appelle a une fonction d'initialisation qui s'appelle init et que notre programme principal a aussi une fonction qui s'appelle init, il risque d'y avoir confusion entre les deux, et python n'aimera pas du tout ça. On risque bien entendu l'insulte et le refus de fonctionner !

Le pendant de ce côté sécurisant est d'avoir un code plus long à taper. Et on ne veut pas nécessairement cela. Python propose donc deux mécanismes supplémentaires pour l'importation des fonctions

Raccourcir le nom

Le premier mécanisme consiste à raccourcir le nom du module, en lui donnant un nom cours propre à notre programme. Considérons par exemple le module random. nous pourrions dans notre programme l'appeler rd. Cela se traduit ainsi en Python :

import p5
import random as rd

vitesseX = rd.uniform(-5,5)

Du coup, pour appeler la fonction de tirage uniforme entre -5 et 5,on n'aurait plus à taper random.uniform(-5,5) mais seulement rd.uniform(-5,5). si on utilise énormément ce module dans notre programme, cela peut être avantageux.

N'importer que le nécessaire

Une autre proposition du langage Python pour l'importation n'est d'importer que le nécessaire et de le mettre dans l'espace de nom principal. On n'importe que les fonctions que l'on va effectivement utiliser, ce qui a pour avantage sur des gros programmes de réduire l'espace mémoire, et on ne risque pas de collision de nom puisque l'on a le contrôle sur les noms. Qui plus est on a pas de préfixe à mettre devant la fonction. Par exemple, au niveau du module random, nous n'utilisons que la fonction uniform. Nous pouvons donc nous contenter d'importer cette seule fonction. Cela va se faire grâce au mot clef from

import p5
from random import uniform

vitesseX = uniform(-5,5)
Et tout importer

Il existe une dernière possibilité, qui est à utiliser avec précaution et que nous allons utiliser par la suite dans notre progression : importer globalement la totalité d'un module. Pour éviter les collisions, il faut le faire le plus rarement possible, mais si on utilise très massivement un module, cela peut être intéressant. Dans notre programme, ce sera le module p5. On lui dit donc d'importer le joker * qui signifie d'importer tout ce que contient le module.

from p5 import *
from random import uniform

vitesseX = uniform(-5,5)

Voilà, on aura plus à écrire de préfixes en p5. On fera directement circle(abscisse,ordonnee,rayon) sans avoir à mettre le p5 devant

On peut importer un module de 4 façons :
  • la plus courante, en lui conservant son espace de nom : import module
  • en raccourcissant son nom : import module as M
  • en important dans l'espace de nom courant le strict nécessaire : from module import fonction1, fonction2
  • (faire attention) en important dans l'espace de nom courant la totalité du module : from p5 import *
reprenez le code ci dessous et modifiez le pour l'alléger en utilisant from p5 import * et from random import uniform
import p5
import random

largeur = 500
hauteur = 500
abscisse = 250
vitesseX = random.uniform(-5,5)
vitesseY = random.uniform(-5,5)
if vitesseX == 0 and vitesseY == 0:
    vitesseX = 1
ordonnee = 250
rayon = 20

def setup():
    p5.size(largeur,hauteur)

def draw():
    global abscisse
    global ordonnee
    global vitesseX
    global vitesseY
    p5.background(0)
    p5.circle(abscisse,ordonnee,rayon)
    abscisse = abscisse + vitesseX
    ordonnee = ordonnee + vitesseY
    if abscisse > largeur :
        abscisse = largeur
        vitesseX = - vitesseX
    if abscisse < 0 :
        abscisse = 0
        vitesseX = -vitesseX
    if ordonnee > hauteur :
        ordonnee = hauteur
        vitesseY = -vitesseY
    if ordonnee < 0 :
        ordonnee = 0 
        vitesseY = - vitesseY

p5.run()

D'une pierre plusieurs coups

Nous avons dans notre code 4 lignes successives pour les variables globales, et au début, nous avons aussi tout un ensemble de ligne pour définir des valeurs. Dans Python, on peut effectuer plusieurs affectation en une fois en séparant avec des virgules. On peut de la même façon importer plusieurs global en utilisant des virgules. Le code au début du programme pourrait ainsi contenir

largeur , hauteur  = 500 ,500
abscisse , ordonnee = 250 , 250
rayon = 20

De la même façon, pour les globales, on pourrait avoir au début de la fonction :

def draw():
    global abscisse, ordonnee, vitesseX, vitesseY

Il ne faut pas abuser des affectations multiples sous peine de rendre le code peu lisible. Le but est de ne pas multiplier de façon trop importante les lignes, pas de tout mettre sur une seule ligne. Il y a un compromis à trouver

Modifiez votre programme pour intégrer ces allégement d'écriture, puis vérifiez qu'il fonctionne toujours en l'éxécutant.

Ces simplifications n'ont pas modifié le fonctionnement du programme, mais elles vont alléger l'écriture, ce dont nous pourrons avoir besoin par la suite. Mais nous allons maintenant passer à quelquechose de nouveau : "ils" sont plusieurs.