Archives de catégorie : DebuterEnPython

LangageModulesQuizz3

Modules Quizz 3

—-

#!python
# fichier small.py
x = 1
y = [ 2, 3 ]
>>> from small import x, y
#!html
<br clear=right>

—-

>>> x = 4


>>> y[0] = 5

>>> import small

>>> small.x, small.y
( 1, [ 5, 3 ] )


#!html
<br clear=right>

—-

>>> reload(small)


>>> small.y, y
( [ 2, 3 ], [ 5, 3 ] )


#!html
<br clear=right>

—-


Attachments

BibliosGui

[wiki: Interfaces graphiques]

#!comment


Loic recommande PyQT ou PySide

PySide ?
http://reseau-loops.github.io/journee_2014_06.html


—-

Tkinter

Encapsulation de Tcl/Tk, livrée avec Python.

Exemple :

#!python


import Tkinter as tk

# il suffit alors de déclarer l'objet Tk()
# qui deviendra la fenêtre principale

fenetre = tk.Tk()

# on crée ensuite un objet Label()
# rattaché à fenetre
# pour afficher du texte non éditable
# on profite du constructeur de l'objet
# pour définir un texte "Hello World"
# dans la foulée (on peut faire autrement)

texte = tk.Label ( fenetre, text="Hello World" )

# l'objet Label() nommé texte est ensuite
# rendu visible dans fenetre grâce à pack()

texte.pack()

# pour finir, on lance la boucle programme

fenetre.mainloop()


En Python 3, Tkinter devient tkinter.

NDLR, question à creuser : si une application est développée avec Tkinter, est-ce que la distribution du produit peu inclure TCL/TK, ou est-ce qu’il faut imposer aux utilisateurs une pré-installation de TCL/TK ?

—-

wxPython

Bibliothèque multi-plateformes pour développer des interfaces graphiques, basée sur la bibliothèque C++ wxWidgets . 5 modules :

  • Windows : Fenêtres, boites de dialogue, frames, etc.
  • GDI : Graphics Device Interface, utilisé pour dessiner.
  • Core : Objets de base, parents des autres.
  • Misc : Logging, joysticks, config. applications, etc.
  • Controls : Boutons, toolbar, etc.

Fenêtre simple :

  • App() : Créer l’application principale (unique).
  • Frame() : Créer une fenêtre.
  • Show() : Afficher la fenêtre.
  • !MainLoop() : Lancer l’application.
  • Move() / MoveXY() : Positionner une fenêtre.
  • !SetPosition() : Positionner une fenêtre.
  • !SetDimensions() : Positionner et dimensionner une fenêtre.
  • Center() : Centrer la fenêtre sur l’écran.
  • !GetClassName() : Récupérer la classe d’un objet.
  • !GetValue() : Récupérer la valeur d’un objet.

Composants standards :

  • Button() : Bouton classique.
  • !ToggleButton() : Bouton à deux états.
  • !RadioButton() : Bouton radio.
  • !StaticLine() : Ligne horizontale ou verticale.
  • !StaticText() : Etiquette de texte.
  • !StaticBox() : Boite encadrée.
  • !ComboBox() : Boite de liste de choix.
  • !CheckBox() : Case à cocher.
  • !StatusBar() : Barre de statut.
  • Gauge() : Barre de progression.
  • Slider() : Potentiomètre linéaire.
  • !SpinCtrl() : « Roulette » numérique.

Exemples :

  • [raw-attachment:code_wx_1.py code_wx_1.py]
  • [raw-attachment:code_wx_2.py code_wx_2.py]
  • [raw-attachment:code_wx_3.py code_wx_3.py]
  • [raw-attachment:code_wx_4.py code_wx_4.py]
  • [raw-attachment:code_wx_5.py code_wx_5.py]
  • [raw-attachment:code_wx_6.py code_wx_6.py]

A retenir :

  • Beaucoup de choses disponibles :
  • En terme de composants graphiques.
  • D’exemples de contrôles graphiques.
  • Librairie graphique complète.
  • Pas d’éditeur d’interfaces graphiques : il faut construire les interfaces « à la main ».

NDLR, question à creuser : si une application est développée avec wxPython, est-ce que la distribution du produit peu inclure wxWidgets, ou est-ce qu’il faut imposer aux utilisateurs une pré-installation de wxWidgets ?

#!html
<br clear=right>

—-

PyQt

Bibliothèque multi-plateformes basée sur Qt (C++).
Offre des composants pas seulement graphiques :

  • Interface graphique (widgets).
  • Accès aux données.
  • Connexions réseaux.
  • Gestion des fils d’exécution.
  • Analyse XML.
  • Etc.

Modules internes :

  • !QtCore, fonctionnalités non graphiques : fichiers, types, threads, etc.
  • QtGUI, composants graphiques : boutons, fenêtres, barre d’outils, couleurs, etc.
  • !QtNetwork : programmation autour du réseau.
  • !QtXml : gestion fichiers XML avec SAX/DOM.
  • !QtSvg : gestion fichiers SVG.
  • !QtOpenGL : gestion affichage 2D/3D.
  • !QtSql : gestion des bases de données.

Exemples de base :

  • Fenêtre simple : [raw-attachment:code_qt_01.py code_qt_01.py].
  • Icône pour une fenêtre : [raw-attachment:code_qt_02.py code_qt_02.py].
  • Tooltips : [raw-attachment:code_qt_03.py code_qt_03.py].
  • Bouton « Quitter » : [raw-attachment:code_qt_04.py code_qt_04.py].
  • Boites de dialogue standards : [raw-attachment:code_qt_05.py code_qt_05.py].
  • Centrage sur l’écran : [raw-attachment:code_qt_06.py code_qt_06.py].

A retenir :

  • Demande de connaître les bases avant.
  • Qt est maintenu et multi-plateformes.
  • Beaucoup de contrôles disponibles.
  • Possible de personnaliser ses propres contrôles.
  • Trouver de nouveaux contrôles :
  • http://code.google.com/p/pyqt4-extrawidgets/
  • http://qt-apps.org/
  • Existe un constructeur d’interfaces : !QtDesigner.

NDLR, question à creuser : si une application est développée avec PyQT, est-ce que la distribution du produit peu inclure Qt, ou est-ce qu’il faut imposer aux utilisateurs une pré-installation de Qt ?

—-

Diverses références

—-


Attachments

LangageGenerateurs

[wiki: Générateurs]

PageOutline

Générateurs

#!comment
Typique de ce que fait xrange au lieu de range en Python 2.
  • C’est une fonction utilisant « yield » au lieu de « return », destinée à fournir une séquence de résultats :
  • l’appel à la fonction retourne un itérateur,
  • chaque appel de next() sur l’itérateur provoque la reprise de l’éxécution de la fonction jusqu’au prochain yield,
  • quand un appel de next() amène à sortir de la fonction sans rencontrer de yield, une exception !StopIteration est levée.

>>> def gen():
... yield 1
... yield 2

>>> g = gen()

>>> g
<generator object gen at ...>

>>> next(g)
1

>>> next(g)
2

>>> next(g)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration


  • Les boucles for et les fonctions supportant les itérateurs peuvent exploiter un générateur.
>>> def fibo(n):
...     a, b = 0, 1
...     while b < n:
...         yield b
...         a, b = b, a + b


>>> for i in fibo(6): print i
1
1
2
3
5

>>> g = fibo(3)

>>> next(g)
1

>>> sum(fibo(6))
12


BibliosData

[wiki: Stockage et manipulation de données]

—-

Module tarfile

Gestion des fichiers TAR, plutôt archivage.

  • open(path, mode) : ecriture / lecture d’un fichier.
  • close() : ferme le fichier actuel.
  • add(path) : ajoute un élément dans le fichier actuel.
  • getnames() : liste des éléments dans le fichier actuel.
  • extract(path, dest) : extraction d’un élément vers destination.

Exercices

  • Créez un fichier TAR contenant tous les fichiers d’une arborescence de votre choix.
  • Listez les éléments contenus dans un fichier TAR.
  • Extraire un élément pour chaque type de fichier.
  • Vérifiez que vous arrivez à ouvrir les fichiers avec les outils « standards » de Windows.
#!html
<br clear=right>

—-

Module zipfile

Gestion des fichiers ZIP, plutôt compression.

  • ZipFile(path, mode) : ecriture / lecture d’un fichier.
  • close() : fermeture du fichier actuel.
  • write(path) : exécute compression et insertion dans fichier actuel.
  • namelist() : liste des éléments stockés dans fichier actuel.
  • getinfo(path) : informations d’un élément dans fichier actuel.
  • read(path) : extraction d’un élément.

Exercices

  • Créez un fichier ZIP contenant tous les fichiers d’une arborescence de votre choix.
  • Listez les éléments contenus dans un fichier ZIP.
  • Extraire un élément pour chaque type de fichier.
  • Vérifiez que vous arrivez à ouvrir les fichiers avec les outils « standards » de Windows.
#!html
<br clear=right>

—-

Module csv

Un fichier CSV est un fichier textuel dont chaque ligne est composée de valeurs séparées par des tabulations, ou des « , », « ; » …

  • DictReader() : lit un fichier CSV.
  • Sniffer() : détecte le dialecte.
  • DictWriter() : ouvre nouveau fichier CSV.
  • writerow() : ecrit une ligne de données.
  • Manipulation de dictionnaires de données :
  • dict_csv['key'] =
  • Méthodes classiques, tri, insertion, etc.
  • Supporte si données en trop ou manquante.

Exercice de manipulation du fichier de données [raw-attachment:short_ex.csv short_ex.csv].

  • Utiliser un dialecte.
  • Chargez le dictionnaire de données.
  • Rajoutez, modifiez des données au dictionnaire.
  • Enregistrez les données dans un autre fichier.
  • Vérifiez que votre nouveau fichier correspond à ce que vous vouliez, sous Excel par exemple, ou un simple éditeur de texte.

(s’inspirer de l’exemple [raw-attachment:code_csv.py code_csv.py])

#!html
<br clear=right>

—-

Modules XML

Fichier XML

  • EXtensible Markup Language.
  • Stockage informations de manière arborescente.
  • Idéal pour fichiers de configuration.
  • Extensible : Vocabulaire et grammaire libres !
  • Générique : Employé pour tout type de données.
  • A l’origine d’autres formats : XHTML, SVG, … le vôtre … etc.
  • Peut être visualisé dans votre navigateur Web préféré.
  • Quelques règles à respecter … quand même !
  • Peut être validé par un fichier de déclaration : DTD.

Exemple simple :

<?xml version="1.0" encoding="utf-8" ?>
<config>
<author>Simon CHOLLET</author>
<email>s.chollet@llr.in2p3.fr</email>
<institut nom="LLR" address="Ecole Polytechnique - 91128 PALAISEAU" />
<date>09/09/2011</date>
<version>1.0</version>
</config>

Technologies XML

  • SAX (Simple Api for XML) : analyse du fichier « au fil de l’eau ». Consomme très peu de mémoire, le fichier n’est pas chargé complètement.
  • DOM (Document Object Model) : représentation orientée objet du contenu. Consomme beaucoup de mémoire si le fichier est gros. Le fichier est chargé et analysé complètement en une seule fois.
  • Python intègre les 2 technologies, modules : sax, dom et ElementTree.
  • De nombreux modules d’analyse de fichiers XML !
  • BeautifulSoup : accepte fichiers mal formés, très utile pour analyse fichiers XHTML, par exemple.

Exercices XML

  • Visualisez les fichiers [raw-attachment:config.xml config.xml] et [raw-attachment:simple.xml simple.xml] dans votre navigateur Web.
  • Regardez le contenu et la déclaration de l’arborescence des données, de ces mêmes fichiers dans un éditeur de texte.
  • Copiez le fichier simple.xml vers un nouveau fichier.
  • Ouvrir le nouveau fichier dans un éditeur de texte, ou éditeur de code.
  • Ajoutez une balise description, avec quelques attributs avec les valeurs que vous souhaitez.
  • Ajoutez du texte entre les balises description.
  • Visualisez votre nouveau fichier dans le navigateur Web.

Exercices SAX

  • Modifiez le code source du fichier [raw-attachment:config_xml.py config_xml.py] pour qu’il puisse prendre en compte la nouvelle balise : ajoutez l’attribut m_desc à la classe SimpleCfg, et modifiez la méthode d’extraction de données pour remplir le nouvel attribut.
  • Modifiez aussi la méthode de visualisation d’objet repr() pour qu’elle affiche le nouvel attribut.
  • Exécutez le programme [raw-attachment:code_sax_xml.py code_sax_xml.py] en modifiant la valeur de XML_SIMPLE_CFG_INPUT_PATH pour pointer vers le chemin du nouveau fichier XML.
  • Vérifiez que vous voyez votre nouvelle balise et attribut(s).

Exercices DOM

  • Fichier [raw-attachment:code_dom_xml.py code_dom_xml.py].
  • Revue de code …
  • Remarquez la manière de remplir les attributs de l’objet configuration.
  • Regardez les méthodes de création de branches.
#!html
<br clear=right>

—-

Bases de données

  • Principe de base : à chaque clé correspond un enregistrement.
  • Important de structurer ses données en pensant dés le début à la clé.
  • Beaucoup de modules existent.
  • Plusieurs manières d’accéder aux bases : sous forme de dictionnaires, d’objets, etc.
  • Base stockée dans fichier ou serveur.
  • Les choix possibles :
  • Fichier : pickle, shelve, SQLite.
  • Serveur : MySQL, SQLAlchemy, Storm.
  • Etc.
#!html
<br clear=right>

—-

Module anydbm

  • DBM : DataBase Manager.
  • Enregistrement de dictionnaires dans fichier.
  • Manipulation de dictionnaire : data[key] = valeur.
  • open() : Ouvre, crée fichier d’enregistrement.
  • close() : Ferme et enregistre le fichier.
  • keys() : Liste les clés disponibles.
  • del, remove() : Supprime enregistrement.

Exemple

import anydbm


villes = ['Dallas', 'Los Angeles', 'New York']
vols = ['1144', '1045', '1520']
horaires = ['14H30', '15H20', '16H20']

# Creation des fichiers DBM villes / horaires
villeDBM = anydbm.open('villes.db', 'n')
horaireDBM = anydbm.open('horaires.db', 'n')
# Ajout des entrees dans les fichiers
idx = 0
for vol in vols:
villeDBM[vol] = villes[idx]
horaireDBM[vol] = horaires[idx]
idx += 1

# Affichage des entrees de la base
print villeDBM.items()
print horaireDBM.items()

# Fermeture des fichiers
villeDBM.close()
horaireDBM.close()


#!html
<br clear=right>

—-

Module pickle/cPickle

  • Module qui sérialise les enregistrements.
  • Pas de notion de clé.
  • Enregistrements stockés les uns à la suite des autres dans le fichier.
  • Fonctionne avec des listes, dictionnaires, objets.
  • Peut utiliser un empaqueteur / dépaqueteur pour enregistrer et extraire les données.
  • Quand c’est disponible, préférez cPickle, écrit en C et plus rapide.
  • ATTENTION : pas de garantie de portabilité de vos données entre des plateformes différentes.
  • open() : Ouvre un fichier.
  • close() : Ferme et enregistre le fichier.
  • dump() : Insère des enregistrements.
  • Pickler() : Empaqueteur de données.
  • Unpickler() : Dépaqueteur de données.
  • load() : Charge des enregistrements.

Exemple 1

vols = {'1144':'Dallas', '1045':'Los Angeles', '1520':'New York'}
horaires = ['14H30', '15H20', '16H20']


# Ouverture du fichier
pkl_file = open(PICKLE_DATA_FILE, "w")

# Creation de l'empaqueteur
packer = pkl.Pickler(pkl_file)

# Enregistrement des donnees
packer.dump(vols)
packer.dump(horaires)
pkl_file.close()

# Lecture des entrees depuis un fichier
pkl_file = open(PICKLE_DATA_FILE, "r")

# Creation du depaqueteur
unpacker = pkl.Unpickler(pkl_file)

# Lecture des donnees
vols_read = unpacker.load()
horaires_read = unpacker.load()
pkl_file.close()


Exemple 2

img_gpib = ImageStore('CableGPIB', '../input/gpib.jpg')
img_oscillo = ImageStore('Oscilloscope', '../input/oscillo.jpg')


# Creation du dictionnaire
img_dict = {'gpib': img_gpib, 'oscillo': img_oscillo}
pkl_file = open(PICKLE_DATA_IMG_FILE, "w")
packer = pkl.Pickler(pkl_file)
packer.dump(img_dict)
pkl_file.close()

pkl_file = open(PICKLE_DATA_IMG_FILE, " r")
unpacker = pkl.Unpickler(pkl_file)
img_dict_read = unpacker.load()
pkl_file.close()
for item in img_dict_read:
img_tmp = img_dict_read[item]
# Contenu de l'image au format chaine de caracteres
img_txt = cStringIO.StringIO()
img_txt.write(img_tmp.m_img)
img_txt.seek(0)
# Enregistrement dans nouveau fichier
img = Image.open(img_txt)
img.save('../output/' + img_tmp.m_desc + '.jpg')


#!html
<br clear=right>

—-

Module shelve

  • Construit au-dessus des modules pickle et anydbm.
  • Accès aux enregistrements par clé, recouvre lacune du module pickle.
  • open() : ouvre un fichier et charge les enregistrements dans un dictionnaire.
  • keys() : liste les clés disponibles dans les enregistrements.
  • close() : ferme et enregistre le fichier.
  • Accès aux données directement comme nous l’aurions fait avec un dictionnaire : db[key].

Exemple

# Les donnees a ecrire
vols = {'1144':'Dallas', '1045':'Los Angeles', '1520':'New York'}
horaires = ['14H30', '15H20', '16H20']


# Creation du gestionnaire de BDD
db = shelve.open(SHELVE_DATA_FILE, 'n')

# Enregistrement des donnees
db['vols'] = vols
db['horaires'] = horaires

# Fermeture du gestionnaire de BDD
db.close()

# Lecture des entrees depuis un fichier
db = shelve.open(SHELVE_DATA_FILE, "r")

# Extraction des cles du fichier
for key in db.keys():
item = db[key]
print " %s: %s" % (key, item)

# Extraction d'une cle particuliere
print " * Vol 1144 :", db['vols']['1144']
db.close()


#!html
<br clear=right>

—-

Module SQLite

  • Utilise un fichier pour stocker les enregistrements, tout est dedans : la structure et les données.
  • Requêtes SQL au travers d’un « curseur » pour accéder aux données, les filtrer, en insérer, etc.
  • Nécessite de connaître la syntaxe SQL.
  • Performant d’un point de vue accès, les filtres sont effectués directement, juste le résultat est donné.
  • Principe :
  • Ouvrir la connexion.
  • Création d’un curseur de parcours de données.
  • Exécution des requêtes : commit.
  • Fermeture du curseur.
  • Fermeture de la connexion à la base.

Exemple

db = sqlite3.connect(SQLITE_DATA_FILE)


# Creation d'un curseur de parcours de donnees
cursor = db.cursor()

# Suppression de la table si elle existe
cursor.execute("DROP TABLE IF EXISTS persons")

# Creation de la table persons de l'annuaire
cursor.execute("""CREATE TABLE persons (ID int PRIMARY KEY ASC, title char(255), ...)""")

# Remplissage de la table
cursor.execute("""INSERT INTO persons VALUES ('1', 'Mr', 'DUPONT', 'Pierre', '1960 06 30' '30')""")

# Sauvegarde des changements
db.commit()

# Extraction des donnees
cursor.execute("SELECT * FROM persons")
for row in cursor:
# Affichage de la ligne
print " > %d, %s, %s, %s, %s, %d" % (row[0], row[1], row[2], row[3], row[4], row[5])

# Fermeture du curseur de parcours de donnees
cursor.close()
db.close()


Exercices :

  • Utilisez le fichier [raw-attachment:code_db_pickle.py code_db_pickle.py] pour rajouter une image dans la liste des images actuelles.
  • Vérifiez lorsque vous exécutez le programme que votre image se trouve bien dans le répertoire output.
  • Utilisez le fichier [raw-attachment:code_db_sqlite.py code_db_sqlite.py] pour (dans l’annuaire) :
  • Ajouter une personne.
  • Modifier une personne
  • Supprimer une personne.
  • Vérifiez, en exécutant le programme, que vos modifications ont été prises en compte.
#!html
<br clear=right>

—-

Module MySQLdb

  • Enregistrement des données sur un serveur.
  • Technologie très largement répandue, notamment dans les applications Web.
  • Accepte de gros volumes et flux de données.
  • Connaître la syntaxe des requêtes SQL …
  • Utilise le module externe MySQLdb.
  • Réagit dans mêmes principes que SQLite : au niveau de la connexion, du curseur, etc.

Exemple : voir [raw-attachment:code_db_mysql.py code_db_mysql.py]

#!html
<br clear=right>

—-

Module pySQLAchemy

Introduction

  • ORM : Object Relational Mapping.
  • Approche orientée objet.
  • La liste des enregistrements est reliée à une liste d’objets.
  • Chaque attribut d’une table de BDD devient un attribut d’objet.
  • Accepte plusieurs types d’interfaces : MySQL, SQLite, etc.
  • Un seul outil pour tous les types de base.
  • Permet facilement de manipuler les enregistrements.

Principe

  • Création classe représentant la structure d’un enregistrement.
  • Création d’un catalogue de données, et d’une table associée.
  • Association de la table et de la classe créée.
  • Connexion à la base de données (session).
  • Exécution des requêtes.
  • Fermeture de la connexion.

Fonctions

  • create_all() : création des tables.
  • drop_all() : supprime des tables.
  • mapper() : associe la table avec une classe.
  • add_all() : permet d’ajouter des enregistrements.
  • commit() : exécute les requêtes.
  • query() : effectue une demande à la base de données.
  • order_by() : trie les données selon un ou plusieurs critères.
  • Etc

Exemple : voir [raw-attachment:code_db_alchemy.py code_db_alchemy.py]

Exercices

  • Utilisez le fichier [raw-attachment:code_db_alchemy.py code_db_alchemy.py] pour :
  • Ajouter un champ à la base : group.
  • Faire de même pour la classe Person : m_group.
  • Modifier la méthode d’affichage de la classe.
  • Rajouter une ligne de visualisation de toutes les personnes de l’annuaire avec le nouveau champ.
  • Vérifiez que le programme fonctionne …
#!html
<br clear=right>

—-

Modules Storm / pyODBC

  • ODBC : Open DataBase Connectivity.
  • pyODBC :
  • Accepte de nombreux types de bases de données.
  • Fonctionne en déclarant un « driver ».
  • Surcouche générique (définie par le standard ODBC).
  • Storm :
  • ORM, comportement identique à pySQLAlchemy.
  • Ne prend pas des méthodes objet (query, order_by, etc.), mais exécute plutôt des requêtes SQL.
#!html
<br clear=right>

—-

Conclusions

Revue des technos de bases de données

  • anydbm : la base, le plus simple.
  • (c)pickle : permet une sérialisation des objets.
  • shelve : introduit la notion de clé en plus de la sérialisation.
  • SQLite : largement utilisé, puissance d’accès équivalente à MySQL.
  • MySQLdb : Permet de déporter sur serveur.
  • SQLAchemy : Approche orientée objet.
  • Exemple de sérialisation d’objet image [raw-attachment:code_db_pickle.py code_db_pickle.py].
  • Exemple d’utilisation Storm : [raw-attachment:code_db_storm.py code_db_storm.py].
  • Exemple d’utilisation pyODBC : [raw-attachment:code_db_odbc.py code_db_odbc.py].

Conclusions sur le stockage

  • Nous avons vu de nombreux moyens de stocker les données plus ou moins compressées d’une application.
  • Chaque technologie a ses avantages et inconvénients :
  • TAR : Archivage ++.
  • ZIP : Compression ++.
  • CSV : Outils de bureautique +.
  • XML : Configuration arborescente ++.
  • SQL : Flux et volumes de données ++.
  • Il faut cependant se préoccuper dans un premier temps de la structure des données d’une application, avant de se plonger tête baissée dans le codage !
  • L’approche orientée objet vue dans les différents modules rend la maintenance du code plus facile, flexible, partageable.

—-


Attachments

LangagePortees

[wiki: Portées]

PageOutline

—-

Résolution des noms : la règle LEGB

On peut réutiliser le même nom à différents endroits du code, la plupart du temps pour désigner des variables et des valeurs différentes.
Résoudre un nom, c’est à dire trouver sans ambiguité à quelle variable il fait référence, consiste à chercher cette variable dans l’ordre suivant, dit LEGB :
1. Local : variables locales de la fonction courante.
1. Enclosing : variables locales des fonctions englobantes (defs et lambdas).
1. Global : variables globales du module courant.
1. Built-in : variables prédéfinies (module builtin).

—-

Assignation à un nom

Par défaut, toute assignation à un nom crée une variable locale, si elle n’existe pas déjà.

#!python


x = 1

def px():
print x

def f1():
x = 2
px()

def f2():
def px():
print x
x = 3
px()

f1()

f2()


#!html
<pre style="margin-left:20px;margin-right:20px;border: 1px solid palegoldenrod;padding:4px;background-color:lightyellow">
1
3
</pre>

—-

Déclaration globales

Le mot clé global permet de préciser qu’un nom désigne une variable globale, c’est à dire au niveau du module courant.

#!python


x = 1

def px():
print x

def f1():
global x
x = 2
px()

f1()


#!html
<pre style="margin-left:20px;margin-right:20px;border: 1px solid palegoldenrod;padding:4px;background-color:lightyellow">
2
</pre>

—-

BibliosSys

[wiki: Système et réseau]

—-

Module sys

Ce module donne accès aux informations et aux commandes du système d’exploitation.

  • sys.path : liste des chemins ou sont recherchés les modules importés.
  • sys.argv : liste des arguments utilisés lors de l’appel au programme python.
  • sys.exit() : fonction qui permet de sortir du programme en cours d’éxécution.
#!html
<br clear=right>

—-

Module os

Ce module permet de manipuler les différentes ressources de l’ordinateur (fichiers, répertoires, processus, …) de façon neutre vis à vis du système d’exploitation sous-jacent.

  • os.name : posix (unix ou MacOS X), nt (windows), mac (avant MacOS X), ou java (jython).
  • getcwd() : renvoie le chemin menant au répertoire courant.
  • abspath(path) : renvoie le chemin absolu de path.
  • listdir(path) : renvoie une liste contenant tous les fichiers et sous-répertoires de path.
  • exists(path) : renvoie True si path designe un fichier ou un répertoire existant, False sinon.
  • isfile(path) : renvoie True si path est un fichier, False sinon.
  • isdir(path) : renvoie True si path est un répertoire, False sinon.
#!html
<br clear=right>

—-

Module re

Les expressions régulières permettent de réaliser des tests ou des transformations complexes sur des chaînes de caractères. L’opération à effectuer est elle-même décrite à l’aide d’une chaîne de caractère spéciale, le « motif » (pattern), dont les caractères ont un sens particulier.

Quelques éléments de syntaxe :

  • « . » : n’importe quel caractère.
  • « ^ » : début de la chaîne ou de la ligne.
  • « $ » : fin de la chaîne ou de la ligne.
  • « * » : 0 à n fois le caractère précédent.
  • « + » : 1 à n fois le caractère précédent.
  • « ? » : 0 à 1 fois le caractère précédent.
  • « \ » : caractère d’échappement.
  • « [ABC] » : le caractère ‘A’ ou ‘B’ ou ‘C‘.
  • « [a-z] » : n’importe quelle lettre minuscule.
  • « [0-9] » : n’importe quel chiffre.

Quelques fonctions du module re :

  • match() : validation conformité chaine.
  • search() : test de présence.
  • findall() : recherche tous les éléments.
  • finditer() : itérateur de recherche.
  • sub() : remplacement de sous-chaine.
  • compile() : compilation pour optimisation.
  • Quand c’est possible, l’usage des méthodes du module string est plu ssimple.

Exemple, analyseur d’adresses web :

# L'expression compilee
exp = re.compile(r"(.*)://([^\/]*)(.*)")


# Definition de la fonction d analyse d adresse
def GetInfosFromURL(url):
try:
return exp.match(url).groups()
except:
return ""

# Analyse d'adresses
protocol, server, path =
GetInfosFromURL("http://doc.python.org/library/re.html")

# Affiche : Protocol : http, Serveur : doc.python.org, Path : /library/re.html
print "Protocol : %s, Serveur : %s, Path : %s" % (protocol, server, path)


#!comment


# L'expression compilee
exp = re.compile(r"^\s*([\w]+)\.([\w]+)\s*=\s*(.*?)\s*$", re.MULTILINE)

# Definition de la classe d'analyse
class Config(dict):
"""Cette classe lit un fichier de configuration et enregistre les
proprietes dans un dictionnaire."""
def init (self, conf file):
dict.init(self)
for p, k, v in exp.findall(file(conf_file).read()):
if not self.has_key(p):
self[p] = {}
self[p][k]=v

# Appel de la fonction d'analyse avec un fichier de configuration
conf_params = Config("ldap.conf")

# Affiche : {'dn': 'uid=simon,ou=person,o=llr,o=com', 'bidon': 'test', 'port': '389', 'server': 'localhost'}
print conf_params["ldap"]

# Affiche : {'port': '8080', 'timeout': '10000', 'server': '127.0.0.1'}
print conf_params["apache"]


#!html
<br clear=right>

—-

Threads

Gestion des threads

  • Exécution parallèle de plusieurs fonctions.
  • Souvent utilisés pour, par exemple :
  • Séparer traitement des données, de l’interface graphique.
  • Exécuter les mêmes opérations sur plusieurs jeux de données.
  • Interruption temporisée : « Timer », exécutée tous les xx secondes.
  • Synchronisation, avec des verrous sur des variables : « locks » ou Files d’attente : « queues ».
  • Temps de partage de CPU dépendent beaucoup de l’OS.
  • Python propose, de base, 2 modules (historique) : thread et threading. Le module threading propose plus de méthodes.
#!comment


  • Attention, pas de priorité d’exécution possible, au contraire des MFC Windows → passer par des processus, plutôt que des threads, si l’on souhaite gérer les priorités.

Modules thread/threading

  • start() : permet de démarrer un thread.
  • run() : méthode appelée lors de l’exécution du thread.
  • isAlive() : savoir si le thread est toujours en vie.
  • Lock() : classe d’objet de verrouillage de données.
  • acquire() : permet de verrouiller une variable.
  • release() : permet de déverrouiller une variable.
  • Queue() : permet de créer une file d’attente.
  • put() : permet de placer un élément dans la file.
  • get() : permet de récupérer un élément dans la file.
  • empty() : permet de savoir si la file d’attente est vide.
  • join() : attendre la fin d’exécution du thread.
  • Timer() : permet de créer un objet Timer.

Plus de threads !

  • Vu que la priorité n’est pas gérée directement, si vous multipliez les threads, il peut y avoir à un moment donné, un ralentissement de tous … La cause : le CPU.
  • Pour le traitement des données massivement parallèle, il existe les calculs sur carte graphique.
  • Le processeur graphique GPU prend la main, mais l’affichage peut s’en trouver affecté si l’on n’installe pas plusieurs cartes graphiques …
  • Modules Python disponibles : pyCUDA, pyOpenCL, mais ça, c’est une autre histoire …

Exemple de Thread

# Fonction de simulation de nettoyage de file d'attente
def CleanQueue(path):
  # Liste des 'jobs‘
  jobs_list = os.listdir(path)
  # Pour tous les 'jobs‘
  for job in jobs_list:
    del_path = "%s/%s" % (path, job)
    # Retire ...
    os.remove(del_path)
    print "Suppression de " + del_path
	
# Chemin des jobs
queue_path = "/tmp/queue"


# Demarre les threads (ici, de BASE)
thread.start_new(CleanQueue, (queue_path, ))
thread.start_new(CleanQueue, (queue_path, ))

while True:
# Rien a faire ...
# Ctrl+C pour arreter
pass


Exemple de Timer

# Fonction de simulation de nettoyage de file d'attente
def CleanQueue(path):
  # Liste des 'jobs‘
  jobs_list = os.listdir(path)
  # Pour tous les 'jobs‘
  for job in jobs_list:
    del_path = "%s/%s" % (path, job)
      # Retire ...
      os.remove(del_path)
      print "Suppression de " + del_path


# Chemin des jobs
queue_path = "/tmp/queue"

# Attente a programmer
wait_time = 600 # = 10 minutes

# Creation du thread temporise
wake_call = threading.Timer(wait_time, CleanQueue, (queue_path, ))

# Demarrage du thread temporise
wake_call.start()


Exercices

  • Créez une fonction qui affiche la date et l’heure.
  • Créez 2 Threads qui exécutent cette fonction.
  • Créez ensuite un Timer qui permet d’exécuter la fonction d’affichage toutes les 5 secondes.
#!html
<br clear=right>

—-

Réseau

Vaste domaine de communication … avec de nombreux protocoles : FTP, HTTP, SMTP, NNTP, NTP, IMAP, etc.

  • Python a, dans sa bibliothèque standard, tous les modules pour répondre à ces problématiques.
  • Principes de base :
  • Un ou plusieurs clients dialogue(nt) avec un serveur, à l’aide d’un noeud appelé « socket ».
  • Les communications sont transmises par différents protocoles.
  • Il existe plusieurs couches prédéfinies de protocoles de communication : couches OSI.

Client FTP : module ftplib
Liste des commandes usuelles :

  • FTP() : permet de créer la connexion avec le serveur FTP.
  • login() : identification sur le serveur, si ce n’est pas déjà fait dans la méthode FTP().
  • nlst() : liste les fichiers distants.
  • retrlines("LIST") : envoie la commande LIST pour lister les fichiers distants.
  • storbinary() : envoie le fichier vers le serveur distant, dans l’arborescence courante.
  • retrbinary() : réceptionne un fichier depuis le serveur distant.
  • rename() : renomme le fichier distant.
  • cwd() : change le répertoire courant sur le serveur distant.
  • mkd() : crée un répertoire sur le serveur distant.
  • delete() : supprime un fichier distant.
  • close() : ferme la connexion.

Exemple

import ftplib


...

ftp = ftplib.FTP(FTP_SERVER_ADDRESS,FTP_SERVER_LOGIN, FTP_SERVER_PASSWD)
print ftp.nlst('public_ftp') # Liste les fichiers distants
print ftp.retrlines('LIST') # Autre facon de lister

# Chemin du fichier a transferer
# Transfere un fichier
local_file_name = "code_wol.py"
local_file = open(local_file_name , 'rb')
ftp.storbinary("STOR %s" % local_file_name, local_file)
local_file.close()

ftp.close()


Client NNTP (Network News Transfer Protocol) : module nntplib
Lecteur de !NewsGroup.

  • NNTP() : Connexion au serveur.
  • group() : récupère les informations sur un groupe de discussions.
  • xhdr() : sélectionne une liste de sujets de discussion.
  • quit() : ferme la connexion avec le serveur.

Exemple :

import nntplib


s = nntplib.NNTP("news.gmane.org")
resp, count, first, last, name = s.group('gmane.comp.python.committers')
print 'Groupe %s, a %s articles : [%s..%s]' % (name, count, first, last)

# Selectionne les 10 derniers
resp, subs = s.xhdr('subject', first + '-' + last)
for id, sub in subs[-10:]:
print id, sub

s.quit()


Client IMAP (Internet Message Access Protocol) : module imaplib
Lecteur d’emails.

  • IMAP4_SSL() : Ouvre une connexion sécurisée (TLS) avec le serveur.
  • IMAP4() : Ouvre une connexion non sécurisée.
  • login() : Identification sur le serveur distant.
  • select() : Sélectionne le répertoire à parcourir.
  • search() : Lance une recherche sur la boite.
  • fetch() : Extrait les messages.
  • logout() : Déconnexion de l’utilisateur.
  • close() : Ferme la connexion avec le serveur.
  • Attention : le programme va changer l’état lu / non lu de vos messages dans votre boite aux lettres.

Exemple :

import imaplib


imap_serv = imaplib.IMAP4_SSL(IMAP_SERVER_ADDRESS,IMAPS_SERVER_PORT)
imap_serv.login(IMAP_SERVER_LOGIN, IMAP_SERVER_PASSWORD)
imap_serv.select() # INBOX par défaut

type, data = imap_serv.search(None, 'ALL')
nb_msg = len(data[0].split())
print " > Nombre de messages : %d" % (nb_msg)

# Affichage des messages trouves
for num in data[0].split():
type, data = imap_serv.fetch(num, '(RFC822)')
print ' --> Message %s\n' % (num)
print '%s' % (data[0][1])
print '--------------------------------------------------\n'

imap_serv.close()
imap_serv.logout()


Client HTTP (!HyperText Transfer Protocol)
Lecture et envoie des commandes par objet « socket » de base.

  • socket() : création de la socket.
  • connect() : ouverture de la connexion avec le serveur.
  • send() : envoie de données sur la socket.
  • recv() : réceptionne des données depuis le serveur.
  • close() : ferme la socket.
  • Plus de fonctionnalités (analyse de page sous forme XHTML) dans le fichier [raw-attachment:code_client_http.py code_client_http.py].

Exercices

  • Utilisez fichier [raw-attachment:code_client_imap.py code_client_imap.py], réglez vos identifiants et serveur pour tester l’accès à votre boite aux lettres. Attention, n’oubliez pas de supprimer les constantes de connexion après.
  • Utilisez le fichier [raw-attachment:code_client_http_base.py code_client_http_base.py], pour tester la connexion avec un serveur Web distant.
  • Utilisez le fichier [raw-attachment:code_nntp_client.py code_nntp_client.py] pour tester la lecture de plusieurs sujets de newsgroup.

—-


Attachments

LangageFonctionnel

[wiki: Programmation fonctionnelle]

—-

Fonctions anonymes

#!comment
ATTENTION : l'abus de fonctions lambda obscurcit le code…
a creuser : http://docs.python.org/3/howto/functional.html
  • Le mot-clé lambda permet de créer une fonction anonyme et jetable.
  • L’instruction return est implicite.
  • On peut avoir plusieurs arguments.
#!python


>>> (lambda a: a**2)(2)
4
>>> f = lambda a: a**2
>>> f(2)
4
>>> def power(n):
... return lambda m: m**n
>>> p3 = power(3)
>>> p3(2)
8
>>> power(3)(2)
8


—-

Compréhensions de listes

#!python


>>> [ abs(x) for x in xrange(-2,2) ]
[ 2, 1, 0, 1 ]

>>> [ x for y in range(2,5) for x in range(y) ]
[ 0, 1, 0, 1, 2, 0, 1, 2, 3 ]

>>> [ x for x in range(-5,5) if x>0 ]
[ 1, 2, 3, 4 ]


—-

References

—-