P
'
t
i
t
e
C
h
a
t
t
e
 
spacer~ IF YOU'RE NOT INTERESTED IN ORAL SEX, KEEP YOUR MOUTH SHUT Articles | Connexion
 
~Un programme Python

Précédent  
  Python  
  Suivant
 Présentation

Cette seconde partie de notre saga consacrée au lanagage Python va nous permettre d'apréhender les fichiers contenant du code source Python. L'étude rapide d'un simple script nous conduira à la découverte des règles fondamentales et des caractéristiques primaires d'un fichier Python.
 Sommaire

6. Module

 AVI Fps

La programme AVI Fps est un petit script de moins d'un kilo-octet dont le but est d'afficher le framerate (nombre de trames par seconde) d'un fichier vidéo AVI. Nous n'allons pas ici tâcher de comprendre son fonctionnement mais simplement nous appuyer dessus pour découvrir Pyhon.

Le code source du script, ou plus précisément du module, aviFps.py est le suivant:

#! /usr/bin/env pyhon
"""
Le module AVI Fps permet de connaître
le framerate d'une vidéo AVI.
"""

import sys

def getAVIFrameRate(fileName):
  "Ouvre une vidéo AVI et calcule son framerate."

  # valeur par défaut
  framerate = 0

  try:
    # ouvre la vidéo
    fsock = open(fileName, "rb", 0)
    # cherche le 128° octet
    fsock.seek(128)

    # valeur scale
    movieScale = _buildInteger(fsock.read(4))
    # valeur rate
    movieRate = _buildInteger(fsock.read(4))
    # calcul du framerate
    framerate = movieRate / movieScale

    # fermeture
    fsock.close()
  except IOError:
    print "Impossible de lire", fileName

  return framerate

def _buildInteger(bytes):
  if len(bytes) != 4:
    return -1
  else:
    return ord(bytes[0]) | ord(bytes[1]) << 8  | \
             ord(bytes[2]) << 16 | ord(bytes[3]) << 24

# point d'entrée
# permet d'utiliser le module comme un programme
if __name__ == "__main__":
  if (len(sys.argv) == 1):
    print """
AVI Fps - Affiche le framerate d'une vidéo AVI

Utilisation: python aviFps.py movie.avi
"""
  else:
    print "AVI Fps - (C)2001 Romain Guy"
    print "Le framerate de", sys.argv[1], "est de",\
           getAVIFrameRate(sys.argv[1]), "fps."
       
      
JextCopier dans Jext | Jext | Plugin Codegeek

 Commentaires

En parcourant ce programme, vous constaterez que deux choses reviennent souvent: les lignes colorées en vert et celles colorées en bleu ciel ou violet.

Toutes les lignes colorées en vert commencent par le caractère # (dièse). Ce sont des commentaires. Un comentaire est délimité par le dièse et par la fin de la ligne. Les commentaires peuvent être insérés à tout endroit: il n'existe aucune règle obligeant les commentaires à se trouver seuls sur une ligne. Ainsi les lignes suivantes sont parfaitement légales:

# donne la valeur 0 à la variable ex
ex = 0
_ex_ = 1 # variable _ex_ vaut 1
       
      
JextCopier dans Jext | Jext | Plugin Codegeek
Le commentaire placé en première ligne a une signification particulière. Les systèmes Unix permettent en effet de rendre exécutable tout fichier. La commande chmod +x aviFps.py permet d'exécuter le programme par le biais de la commande: ./aviFps.py. Pour cela le système doit connaître l'interpréteur lié au fichier. C'est le but de la première ligne. Nous déclarons ici que l'interpréteur Python est invoqué par la commande /usr/bin/env python.


 Chaînes

Les séquences en bleu clair ou violet sont des chaînes de caractères. Pourquoi sont-elles affichées différement alors ? Python permet d'utiliser ce que l'on nomme des verbatim strings (ce concept existe également dans le langage C# par exemple). Une chaîne de ce type sera affichée telle qu'elle à l'écran. Les séquences d'échappement classiques (comme le retour à la ligne \n) ne seront pas traduites mais affichées directement. Les chaînes verbatim sont très pratiques pour afficher des messages de plusieurs lignes.

Les deux instructions suivantes produisent le même résultat (affichage d'un message de plusieurs lignes dans la console):

print "Hello world !\nPython est sur www.programmationworld.com"
print """Hello world !
Python est sur www.progx.org"""
       
      
JextCopier dans Jext | Jext | Plugin Codegeek
Une chaîne verbatim est déclarée en utilisant trois guillemets doubles (""") en lieu et place d'un seul. Python accepte également les guillemets simples (') pour créer des chaînes. Cela permet d'utiliser l'autre type de guillement sans séquence d'échappement. Par exemple, les séquences:

"- As-tu vu \"Man On The Moon\" ?"
'- Non, et toi tu as vu \'Bullworth\' ?'
       
      
JextCopier dans Jext
pourront être remplacées efficacement par les instructions suivantes:

'- As-tu vu "Man On The Moon" ?'
"- Non, et toi tu as vu 'Bullworth' ?"
       
      
JextCopier dans Jext
Vous noterez que certaines chaînes de caractères semblent se promener dans le code source, sans faire partie de quelque instruction que ce soit. Il s'agit là d'une caractéristique intéressante des programmes Python: la documentation fait partie du langage. Une chaîne de caractère placée en début de fichier correspond à la documentation du module et une chaîne suivant une déclaration de fonction ou de classe documente l'entité. Ces chaînes sont utilisées par les IDE notamment pour afficher des aides.


 Indentation et blocs de code

La seconde chose remarquable dans un code source Python est l'indentation. Celle-ci joue un rôle vital dans ce langage. Les blocs de code ne sont pas délimités par des caractères ou des mots réservés spéciaux (tels que les { du C ou les End du Visual Basic). L'indentation seule compte. Ceci paraît difficile de prime abord mais une fois habitué à ce système, votre vitesse de développement n'en sera que décuplée.

Python laisse toute latitude à l'utilisateur quant à la méthode d'indentation choisie. Il est cependant nécessaire que celle-ci reste la même tout au long du fichier. Vous pouvez ainsi parfaitement utiliser les tabulations ou les espaces, mais ne mélangez pas les deux. Vous pouvez utiliser 5 espaces comme unité d'indentation, ou trois, etc... Mais respectez toujours votre choix.

Nous avons vu que Python ne possédait pas de délimiteurs. En fait, c'est faux. Python possède un type de délimiteur particulier, le "deux-points" (:). Ceux-ci sont obligatoires à la fin des instructions débutant un bloc de code: if, for, while, try, else...

Voici un exemple de code mal formé:

if test == 1:
print "test vaut bien 1"
       
      
JextCopier dans Jext | Jext | Plugin Codegeek
Dans cette exemple, et malgré la présence des deux points, la ligne print sera toujours exécutée. L'indentation de celle-ci n'étant pas supérieure à celle du if, Python ne considérera pas cette ligne comme faisant partie du bloc de condition. L'interpréteur générera même une erreur. En effet, un bloc de code vide (équivalent du { } en C++ ou Java) est défini par un mot-clé: pass. Voici un code faux, mais interprétable:

if test == 1:
  pass
print "test vaut bien 1"
       
      
JextCopier dans Jext
Pour terminer voici donc l'écriture correcte de notre test:

if test == 1:
  print "test vaut bien 1"
       
      
JextCopier dans Jext
L'emploi d'une indentation parfaite interdit malheureusement les retours à la ligne inopiné au beau milieu d'une instruction. Or, tout le monde sait combien il est agaçant de devoir faire défiler son code source horizontalement pour le lire. Une parade existe: il s'agit de l'anti-slash (\). Le programme AVI Fps possède une telle ligne (celle employant l'opérateur <<). Il suffit de placer un \ en fin de ligne puis de continuer l'instruction, sans se soucier de l'indentation.

Vous constaterez qu'à la longue, cette spécifité de Python évite de nombreuses erreurs, ou tout du moins permet de les répérer plus facilement.


 Exécution

Nous avons parlé dans ce cours de module au lieu de script. Nous pourrions généraliser en disant qu'un script est un module exécutable. L'exécution d'un module est rendue possible par le bias de la ligne:

if __name__ == "__main__":
       
      
JextCopier dans Jext | Jext | Plugin Codegeek
Dans un module, __name__ est un attribut du module. Cet attribut a pour valeur "__main__" lorsque le module est interprété par la commande: python module.py. C'est ainsi que nous pouvons faire d'un module un programme exécutable.

Mais qu'est-ce qu'au juste un module ? Un module est un fichier contenant des méthodes, des classes et des attributs. Ceux-ci, à moins d'être privés (à l'instar de la méthode _buildInteger() de notre exemple), sont accessible à d'autres modules ou scripts grâce aux mots réservés import et from.

La clause import permet d'incorporer le nom d'un module dans le namespace courant. Dans notre exemple, nous pouvons lire la ligne:

import sys
       
      
JextCopier dans Jext
Cette ligne signifie "nous importons le nom sys dans le namespace pour rendre son utilisation valide". Nous pouvons ensuite faire référence au module sys. Le programme AVI Fps lit l'attribut argv du module sys dans la condition d'exécution. Sans la clause d'importation, les lignes contenant sys.argv seraient déclarées comme érronées.

La clause from permet d'aller un petit peu plus loin. En effet, l'importation d'un module nécessite la réécriture de son nom devant chaque appel à une fonction ou classe qu'il contient. Pour remédier à cela, nous pouvons utiliser from:

from sys import argv
       
      
JextCopier dans Jext
Grâce à ceci nous pourrons appeler directement la variable argv plutôt que sys.argv. Notez enfin que les mots from et include sont utilisables en tout endroit du programme (dans un if, un for, etc...).


 Module

Puisque que notre fichier est un module, nous pouvons tenter de l'appeler depuis un autre fichier. Voici notre première tentative qui emploie simplement import (le fichier sera nommé aviImport.py et placé dans le même répertoire que aviFps.py):

import aviFps
print aviFps.getAVIFrameRate("D:\\405TheMovie.avi")
       
      
JextCopier dans Jext | Jext | Plugin Codegeek
Et cela marche parfaitement ! Nous pouvons aussi créer le fichier aviFrom.py contenant les lignes suivantes:

from aviFps import getAVIFrameRate
print getAVIFrameRate("D:\\405TheMovie.avi")
       
      
JextCopier dans Jext
Et ô miracle, cela marche encore !


 Téléchargement

Vous pouvez télécharger le script aviFps.py ainsi que les deux scripts de test des clauses d'import: AVIFps.zip.



par Romain Guy
romain.guy@jext.org
http://www.jext.org
Dernière mise à jour : 14/10/2006


Précédent  
  Python  
  Suivant

 
#ProgX©2005 Mathieu GINOD - Romain GUY - Erik LOUISE