Archives de catégorie : DebuterEnPython

BibliosParallelisme

= [wiki: Python parallèle]
PageOutline

#!comment


A bosser
import concurrent.futures
https://pythonhosted.org/joblib/parallel.html

http://www.tutorialspoint.com/python/python_multithreading.htm
https://bitbucket.org/stackless-dev/stackless/wiki/Home


== Asynchronous programming

== Starting a New Thread

To spawn another thread, you need to call following method available in
thread module:

#!python


thread.start_new_thread ( function, args[, kwargs] )


This method call enables a fast and efficient way to create new threads in both Linux
and Windows.

The method call returns immediately and the child thread starts and calls function
with the passed list of agrs. When function returns, the thread terminates.

Here, args is a tuple of arguments; use an empty tuple to call function without
passing any arguments. kwargs is an optional dictionary of keyword arguments.

#!python


import thread
import time

# Define a function for the thread
def print_time( threadName, delay):
count = 0
while count < 5:
time.sleep(delay)
count += 1
print "%s: %s" % ( threadName, time.ctime(time.time()) )

# Create two threads as follows
try:
thread.start_new_thread( print_time, ("Thread-1", 2, ) )
thread.start_new_thread( print_time, ("Thread-2", 4, ) )
except:
print "Error: unable to start thread"

while 1:
pass


When the above code is executed, it produces the following result −

Thread-1: Thu Jan 22 15:42:17 2009
Thread-1: Thu Jan 22 15:42:19 2009
Thread-2: Thu Jan 22 15:42:19 2009
Thread-1: Thu Jan 22 15:42:21 2009
Thread-2: Thu Jan 22 15:42:23 2009
Thread-1: Thu Jan 22 15:42:23 2009
Thread-1: Thu Jan 22 15:42:25 2009
Thread-2: Thu Jan 22 15:42:27 2009
Thread-2: Thu Jan 22 15:42:31 2009
Thread-2: Thu Jan 22 15:42:35 2009

Although it is very effective for low-level threading, but the thread module is
very limited compared to the newer threading module.

== The Threading Module

The newer threading module included with Python 2.4 provides much more powerful,
high-level support for threads than the thread module discussed in the previous section.

The threading module exposes all the methods of the thread module and provides
some additional methods:

  • threading.activeCount(): Returns the number of thread objects that are active.
  • threading.currentThread(): Returns the number of thread objects in the caller’s thread control.
  • threading.enumerate(): Returns a list of all thread objects that are currently active.

In addition to the methods, the threading module has the Thread class that implements
threading. The methods provided by the Thread class are as follows:

  • run(): The run() method is the entry point for a thread.
  • start(): The start() method starts a thread by calling the run method.
  • join([time]): The join() waits for threads to terminate.
  • isAlive(): The isAlive() method checks whether a thread is still executing.
  • getName(): The getName() method returns the name of a thread.
  • setName(): The setName() method sets the name of a thread.

== Creating Thread Using Threading Module

To implement a new thread using the threading module, you have to do the following −

  • Define a new subclass of the Thread class.
  • Override the init(self [,args]) method to add additional arguments.
  • Then, override the run(self [,args]) method to implement what the thread should

do when started.

Once you have created the new Thread subclass, you can create an instance of it and
then start a new thread by invoking the start(), which in turn calls run() method.

#!python


import threading
import time

class myThread (threading.Thread):
def init(self, threadID, name, delay):
threading.Thread.init(self)
self.threadID = threadID
self.name = name
self.delay = delay
def run(self):
print "Starting " + self.name
print_time(self.name, self.delay, 5)
print "Exiting " + self.name

def print_time(threadName, delay, counter):
while counter:
time.sleep(delay)
print "%s: %s" % (threadName, time.ctime(time.time()))
counter -= 1

# Create new threads
thread1 = myThread(1, "Thread-1", 1)
thread2 = myThread(2, "Thread-2", 2)

# Start new Threads
thread1.start()
thread2.start()

print "Exiting Main Thread"


When the above code is executed, it produces the following result:

Starting Thread-1
Starting Thread-2
Exiting Main Thread
Thread-1: Thu Mar 21 09:10:03 2013
Thread-1: Thu Mar 21 09:10:04 2013
Thread-2: Thu Mar 21 09:10:04 2013
Thread-1: Thu Mar 21 09:10:05 2013
Thread-1: Thu Mar 21 09:10:06 2013
Thread-2: Thu Mar 21 09:10:06 2013
Thread-1: Thu Mar 21 09:10:07 2013
Exiting Thread-1
Thread-2: Thu Mar 21 09:10:08 2013
Thread-2: Thu Mar 21 09:10:10 2013
Thread-2: Thu Mar 21 09:10:12 2013
Exiting Thread-2

== Synchronizing Threads

The threading module provided with Python includes a simple-to-implement locking
mechanism that allows you to synchronize threads. A new lock is created by calling
the Lock() method, which returns the new lock.

The acquire(blocking) method of the new lock object is used to force threads to
run synchronously. The optional blocking parameter enables you to control whether
the thread waits to acquire the lock.

If blocking is set to 0, the thread returns immediately with a 0 value if the lock
cannot be acquired and with a 1 if the lock was acquired. If blocking is set to 1,
the thread blocks and wait for the lock to be released.

The release() method of the new lock object is used to release the lock when it
is no longer required.

#!python


import threading
import time

class myThread (threading.Thread):
def init(self, threadID, name, counter):
threading.Thread.init(self)
self.threadID = threadID
self.name = name
self.counter = counter
def run(self):
print "Starting " + self.name
# Get lock to synchronize threads
threadLock.acquire()
print_time(self.name, self.counter, 3)
# Free lock to release next thread
threadLock.release()

def print_time(threadName, delay, counter):
while counter:
time.sleep(delay)
print "%s: %s" % (threadName, time.ctime(time.time()))
counter -= 1

threadLock = threading.Lock()
threads = []

# Create new threads
thread1 = myThread(1, "Thread-1", 1)
thread2 = myThread(2, "Thread-2", 2)

# Start new Threads
thread1.start()
thread2.start()

# Add threads to thread list
threads.append(thread1)
threads.append(thread2)

# Wait for all threads to complete
for t in threads:
t.join()
print "Exiting Main Thread"


When the above code is executed, it produces the following result:

Starting Thread-1
Starting Thread-2
Thread-1: Thu Mar 21 09:11:28 2013
Thread-1: Thu Mar 21 09:11:29 2013
Thread-1: Thu Mar 21 09:11:30 2013
Thread-2: Thu Mar 21 09:11:32 2013
Thread-2: Thu Mar 21 09:11:34 2013
Thread-2: Thu Mar 21 09:11:36 2013
Exiting Main Thread

== Multithreaded Priority Queue

The Queue module allows you to create a new queue object that can hold a specific
number of items. There are following methods to control the Queue:

  • get(): The get() removes and returns an item from the queue.
  • put(): The put adds item to a queue.
  • qsize() : The qsize() returns the number of items that are currently in the queue.
  • empty(): The empty( ) returns True if queue is empty; otherwise, False.
  • full(): the full() returns True if queue is full; otherwise, False.
#!python


import Queue
import threading
import time

exitFlag = 0

class myThread(threading.Thread):
def init(self, threadID, name, q):
threading.Thread.init(self)
self.threadID = threadID
self.name = name
self.q = q
def run(self):
print "Starting " + self.name
process_data(self.name, self.q)
print "Exiting " + self.name

def process_data(threadName, q):
while not exitFlag:
queueLock.acquire()
if not workQueue.empty():
data = q.get()
queueLock.release()
print "%s processing %s" % (threadName, data)
else:
queueLock.release()
time.sleep(1)

threadList = ["Thread-1", "Thread-2", "Thread-3"]
nameList = ["One", "Two", "Three", "Four", "Five"]
queueLock = threading.Lock()
workQueue = Queue.Queue(10)
threads = []
threadID = 1

# Create new threads
for tName in threadList:
thread = myThread(threadID, tName, workQueue)
thread.start()
threads.append(thread)
threadID += 1

# Fill the queue
queueLock.acquire()
for word in nameList:
workQueue.put(word)
queueLock.release()

# Wait for queue to empty
while not workQueue.empty():
pass

# Notify threads it's time to exit
exitFlag = 1

# Wait for all threads to complete
for t in threads:
t.join()
print "Exiting Main Thread"


When the above code is executed, it produces the following result −

Starting Thread-1
Starting Thread-2
Starting Thread-3
Thread-1 processing One
Thread-2 processing Two
Thread-3 processing Three
Thread-1 processing Four
Thread-2 processing Five
Exiting Thread-3
Exiting Thread-1
Exiting Thread-2
Exiting Main Thread

WikiStart – DebuterEnPython

#!comment


A évaluer :

  • http://www.openbookproject.net/books/bpp4awd/index.html
  • http://python.developpez.com/cours/apprendre-python-3/
  • https://ionisx.com/courses/55a6713b1acee19002fa5d17/python-pour-les-scientifiques/description

Installer http://trac-hacks.org/wiki/TracWikiToPdfPlugin ?

https://owncloud.ias.u-psud.fr/public.php?service=files&t=f8e1fea5fd0792016e0bd7b8b1da8064&path=//1%20-%20Start

IMPORTANT

=

Avant d'attaquer les modules/bibliothèques extérieurs, faire le point
sur les outils d'isntallation : python eggs et compagnies...

DEBREIFING 2012

===

Les types de slides récurrents :

  • Définition
  • Trucs et astuces
  • Bonnes pratiques
  • Syntactic sugar

Gros boulots :

  • repasser tous les prints en version 2
  • refaire la chasse aux comparatifs Python 2 et 3 et tout refactoriser dans la zone prévue pour.
  • plutot que des morales, faire des "slides" "Bonnes Pratiques"

Thématiques à considérer :

  • les "vars", qui permettraient d'automatiser des créations de variables en masse
  • attention à "del", apparemment considéré comme à éviter ?!?

Point à vérifier :

  • l'opérateur ** fonctionnerait aussi sur les réels ?!?

Idées d'exercices :

  • pour les générateurs, écrire un xrange.

A développer :

A ajouter : THREADS ???

Idée : un module sur les differences C++/Python
- duck typing
- le passage d'arguments
- l'héritage multiple
- la surcharge "traitée à la main"


#!div class="wiki-toc"


Sites officiels

Distributions

Outils

Tutoriaux en ligne

Livres

Divers

== Tour d’horizon

Installez Anaconda, en version Python 3.4.

Bases du langage

Outillage

#!comment


Orientation objets

== Complément de bagages

#!comment


A LA RECHERCHE DES BENEFICES D'UN LANGAGE COMPILE :
- slots

DECORATEURS ?
http://gillesfabio.com/blog/2010/12/16/python-et-les-decorateurs/
De fonctions ?
De classes ?

Type Hinting ?
http://blog.jetbrains.com/pycharm/2015/11/python-3-5-type-hinting-in-pycharm-5/


Annexes

Bibliotheques

à partir de présentations de Simon Chollet

En travaux

© //David Chamont, Laboratoire Leprince-Ringuet (LLR) / IN2P3 / CNRS, Ecole polytechnique / Université Paris-Saclay//br
© //Ce(tte) œuvre est mise à disposition selon les termes de la Licence Creative Commons Attribution – Partage dans les Mêmes Conditions 4.0 International// [=#license]

#!comment






Le programme de la formation INRIA :

Introduction

Python en quelques phrases
L’esprit Python
Une courte histoire de Python
Python et les autres langages
Découverte de l’interpréteur, premiers programmes

Les éléments du langage

Une vue d’ensemble
Les entrées/sorties standard
Les structures de contrôle
Le types de base
Les conventions de codage

Les fonctions

Une vue d’ensemble
La portée des variables
Signatures des fonctions
La documentation des fonctions
Fonctions anonymes (lambda)

Concepts avancés

Les fermetures (closures)
Les décorateurs de fonctions
Les générateurs
Fonctions récursives
Programmation fonctionnelle

L’approche objet

Classes et instances
Les attributs
Les méthodes
La méthode init()
La documentation des classes
Héritage
Old style / New style classes
Polymorphisme
Encapsulation
Agrégation d’objets
Méthodes de classe
La surcharge des opérateurs

Modules et paquets

Modules
Paquets

La bibliothèque standard en bref

La manipulation des fichiers
Le module sys
L’interface avec le système d’exploitation
Les (sous)processus
Le module platform
L’accès à Internet
Compression des données
ConfigParser et json
Mesure des performances
Le module math
Le module random
Les expressions rationnelles (ou régulières)

Les tests

Le module doctest
Le module unittest

Outils divers

L’installeur Pip
Les environnements virtuels
Le débogueur pdb
Le module future


Outillage

[wiki: Outils de base]

PageOutline

Implémentations de Python

  • CPython : la plus courante, écrite en langage C.
  • Jython : alternative en Java, utilisant la JVM Java.
  • !IronPython : alternative basée sur .NET .
  • !PyPy : alternative écrite en Python.

Interpréteur en ligne de commande

Options courantes :

  • -c : exécute la commande passée en argument,
  • -i : passe en mode interactif après avoir exécuter un script ou une commande,
  • -d : mode debug.

Environnements de développement

Outils d’installation de paquets additionnels

Distutils

Disutils est un ensemble d’outils permettant de construire des distributions (ensemble de modules distribués ensemble) prêtes à être installées, par exemple un « rpm » pour linux, ou bien des distributions de fichiers source.

Pour installer une telle distribution de fichiers sources :
1. télécharger le fichier d’archive, généralement un tarball sous unix et zip sous windows ;
1. procéder à l’extraction des fichiers,
1. lancer la commande python setup.py install

Cette commande va copier les fichiers de build/lib (ou build/lib.<platform>) vers le répertoire réservé aux modules tiers de l’installation Python. Les répertoires par défaut sont :

  • Sous Windows: C:\PythonXY\Lib\site-packages
  • Sous Unix: /usr/local/lib/pythonX.Y/site-packages

Certaines options permettent de choisir d’autres répertoires d’installation :

  • python setup.py install --user : installation dans $HOME/.local/lib/pythonX.Y/site-packages
  • python setup.py install --home=<dir> : installation dans <dir>/lib/python
  • python setup.py install --prefix=<dir> : installation dans <dir>/lib/pythonX.Y/site-packages

Setuptools, Python Eggs & easy_install

L’extension Setuptools améliore sensiblement Distutils.

Elle définit un nouveau format d’archive qui prend en compte les dépendances, le format egg (ce format est maintenant appelé à être remplacé par le nouveau format « wheel »).

Pour installer une distribution Egg, utilisez easy_install.

!PyPi & Pip

Le Python Package Index (!PyPi) sert de dépôt central officiel pour toutes les distributions que les développeurs veulent partager.

Pour installer des distributions externes, on conseille maintenant d’utiliser Pip (Python installing package). De conception plus récente qu’easy_install, cet outil cherche les distributions demandées sur le Python Package Index (!PyPi), et gère les dépendances entre distributions. MAIS il ne gère pas le format Egg.

!PyPi & Pip

Le Python Package Index (!PyPi) sert de dépôt central officiel pour toutes les distributions que les développeurs veulent partager. Distutils dispose de commandes pour transférer une distribution sur !PyPi. La nouvelle commande twine permet de le faire de façon plus sécurisée.

Pour installer des distributions externes, on vous conseille maintenant d’utiliser Pip (Python installing package). De conception plus récente qu’easy_install, cet outil cherche les distributions demandées sur le Python Package Index (!PyPi), et gère les dépendances entre distributions. MAIS il ne gère pas le format Egg.

#!comment


Références

Setuptools, Python Eggs & easy_install

L'extension Setuptools améliore sensiblement distutils.

  • Découverte automatique des paquets : find_packages() calcule automatiquement la valeur à passer à l'argument package de la fonction setup().
  • Gestion des dépendances : install_requires, un nouvel argument de setup(), permet lister les autres distributions dont dépend la distribution courante.
  • Format egg : format d'archive amélioré. Il est maintenant appelé à être remplacé par le nouveau format wheel.

Par ailleurs, les Setuptools disposent d'un mode "développement". Plutôt que d'installer vraiment une distribution en cours de développement, vous pouvez créer temporairement dans la zone d'installation un lien symbolique vers le répertoire courant, de façon que vos modifications soient instantanément visibles à un client extérieur. Cette pseudo-installation se fait avec la commande python setup.py develop. Pour sortir de ce mode développement en supprimant le lien symbolique, utilisez la commande python setup.py develop --uninstall.

Enfin, l'extension fournit une nouvelle commande d'installation d'une distribution egg, easy_install, qui prend en compte les dépendances définies par install_requires.


OutillageProfilage

[wiki: Profilage]

PageOutline

#!comment


https://www.cognitoforms.com/COMSOFT1/IntelAcc%C3%A9l%C3%A9rezVotreCodePythonOct16

METTRE A JOUR A PARTIR DE LA PRESENTATION PYTHRAN DE LOIC : http://python-scientific-lecture-notes.developpez.com/tutoriels/note-cours/apprendre-python-optimisation-code/
VERIFIER AUSSI : http://python-scientific-lecture-notes.developpez.com/tutoriels/note-cours/apprendre-python-optimisation-code/

http://pypy.org/ (sandbox, stackless execution)


fibo.py :

#!python
def fib(n):
    # from http://en.literateprograms.org/Fibonacci_numbers_(Python)
    if n == 0:
        return 0
    elif n == 1:
        return 1
    else:
        return fib(n-1) + fib(n-2)


def fib_seq(n):
seq = [ ]
if n > 0:
seq.extend(fib_seq(n-1))
seq.append(fib(n))
return seq


Module timeit

Ce module permet de répéter un certain nombre de fois une instruction donnée, au sein d’un environnement virtuel isolé, et de mesurer son temps d’éxécution :

>>> import timeit
>>> t = timeit.Timer("print fib_seq(20); print","import fibo")   1
>>> t.timeit()
8.21683733547
>>> t.repeat(3, 2000000)
[16.48319309109, 16.46128984923, 16.44203948912]

Modules profile, cProfile et pstats

Le module profile permet d’obtenir des statistiques sur le temps passé dans les différentes fonctions :

#!python


>>> import profile
>>> import fibo
>>> profile.run('print fib_seq(20); print')


Le module cProfile est une variante optimisée, à utiliser en priorité lorsqu’elle est disponible pour votre configuration.

On peut utiliser pstats pour faire des statistiques d’exécution et améliorer la mise en page et les informations affichées :

#!python


import profile
import pstats
import fibo

# Create 5 set of stats
filenames = []
for i in range(5):
filename = 'profile_stats_%d.stats' % i
profile.run('print %d, fib_seq(20)' % i, filename)

# Read all 5 stats files into a single object
stats = pstats.Stats('profile_stats_0.stats')
for i in range(1, 5):
stats.add('profile_stats_%d.stats' % i)

# Clean up filenames for the report
stats.strip_dirs()

# Sort the statistics by the cumulative time spent in the function
stats.sort_stats('cumulative')

# limit output to lines with "(fib" in them
stats.print_stats('\(fib')


Gprof2Dot

Références

LangageVersions

[wiki: Python 2 vs 3]

PageOutline

#!comment''
CLASSES NEW STYLE ?

METTRE A JOUR AVEC LES INFOS DU MOOC

Instructions et fonctions prédéfinies

Print

En Python 2, print était une instruction.

#!python


titre = 'exemple'
ligne = '='*len(titre)
print titre, '\n', ligne


#!html
<pre style="margin-left:50px;border: 1px solid palegoldenrod;padding:10px;background-color:lightyellow">
exemple


=

</pre>


Dans l’exemple ci-dessous, on n’appelait pas une fonction print(), mais on appelait l’instruction print qui est suivie d’une valeur entre parenthèses.

#!python


print('exemple')


#!html
<pre style="margin-left:50px;border: 1px solid palegoldenrod;padding:10px;background-color:lightyellow">
exemple
</pre>

Dans l’exemple ci-dessous, on n’appelait pas une fonction print(), mais on appelait l’instruction print qui est suivie d’un tuple de trois éléments.

#!python


titre = 'exemple'
ligne = '='*len(titre)
print(titre,'\n',ligne)


#!html
<pre style="margin-left:50px;border: 1px solid palegoldenrod;padding:10px;background-color:lightyellow">
('exemple', '\n', '=======')
</pre>

En Python 3, print() est une fonction.

#!python


titre = 'exemple'
ligne = '='*len(titre)
print(titre,ligne,sep='\n')


#!html
<pre style="margin-left:50px;border: 1px solid palegoldenrod;padding:10px;background-color:lightyellow">
exemple


=

</pre>


Input

En Python 2, input() interprétait le texte saisi, raw_input() ne l’interprétait pas.

En Python 3, input() n’interprète pas le texte saisi (il faut faire eval(input())).

Iteration

La méthode d’itération s’appellait next() en Python 2, et devient next() en Python 3.

Range

En Python 2, l’usage de range() était découragé en cas de grandes valeurs, au profit de xrange(), qui ne renvoie pas une liste préconstruite de tous les entiers demandés, mais les prépare et les fournit un par un, au fur et à mesure du besoin.

En Python3, range() reprend l’ancien comportement de xrange().

Map

En Python 2, la fonction map() renvoie une liste, directement imprimable.

En Python3, la fonction map() renvoie un itérateur, qu’il faut parcourir ou transformer en liste pour pouvoir l’imprimer.

Chaines de caractères

Types de caractères

En Python 2, les chaînes étaient par défaut des séquences de caractères ASCII. On pouvait explicitement obtenir une chaîne unicode à l’aide du préfixe « u » : s4 = u"chaine unicode".

En Python 3, les chaînes deviennent des séquences de caractères unicode. On peut explicitement obtenir une chaine d’octets (type bytes) à l’aide du préfixe « b » : s4 = b"chaine unicode".

Méthodes et fonctions

Avant les dernières versions de Python 2, on manipulait les chaînes à l’aide des fonctions du module string. A présent, on utilise les méthodes du type str, y compris sur des littéraux :

>>> elements = 'A/B/C'.split('/')
>>> print('|'.join(elements))
A|B|C

Formatage

L’opérateur historique pour le formattage des chaines est le %, basé sur une syntax inspirée du « printf » du langage C :

>>> mois = ['Janvier','Fevrier','Mars','Avril','Mai','Juin',
            'Juillet','Aout','Septembre','Octobre','Novembre','Decembre']
>>> print "Vous avez choisi %s" % mois[3]
Vous avez choisi Avril

Cependant, il est appelé à disparaitre, au profit de la méthode str.format()

>>> mois = ['Janvier','Fevrier','Mars','Avril','Mai','Juin',
            'Juillet','Aout','Septembre','Octobre','Novembre','Decembre']
>>> print("Vous avez choisi {0}".format(mois[3]))
Vous avez choisi Avril

Calcul numerique

Types entiers

En Python 2, nous disposions de deux types :

  • int (équivalent d’un long du C) : 1234, 045, 0xFC
  • long (sans limite de taille) : 999L

Les objets glissent automatiquement du type int à long lorsqu’ils deviennent trop grands. On peut mélanger entiers courts et longs dans des opérations, le résultat étant systématiquement un long.

En Python 3, il n’y plus qu’un seul type int combinant précision illimitée et représentation interne optimisée.

Division

En Python 2, en présence d’entiers, / appliquait un quotient entier et retournait un entier, à la façon de //.

>>> 2/3
0
>>> 2./3.
0.6666…
>>> 6/2
3
>>> 6./2.
3.0

En Python 3, / applique toujours une division classique et retourne toujours un nombre flottant.

>>> 2/3
0.6666…
>>> 2./3.
0.6666…
>>> 6/2
3.0
>>> 6./2.
3.0

Importation de module

En Python 2, les produits à importer sont recherchés en priorité dans le répertoire/package courant :

#!python
# fichier pkg/init.py
import mod
#!python
# fichier pkg/mod.py
print name
#!python
# fichier mod.py
print name
>>> import pkg
pkg.mod

En Python 3, le répertoire/package courant est ignoré :

#!python
# fichier pkg/init.py
import mod
#!python
# fichier pkg/mod.py
print(name)
#!python
# fichier mod.py
print(name)
>>> import pkg
mod

On peut obtenir un import « relatif » en Python 3 à l’aide de l’instruction from ..

#!python
# fichier pkg/init.py
from . import mod
#!python
# fichier pkg/mod.py
print(name)
#!python
# fichier mod.py
print(name)
>>> import pkg
pkg.mod

On peut également obtenir l’import « global » de Python3 en Python 2 grâce à la commande from !future! import absolute_import.

  • En python 2
#!python
# fichier pkg/init.py
from future import absolute_import
import mod
#!python
# fichier pkg/mod.py
print name
#!python
# fichier mod.py
print name
>>> import pkg
mod

ATTENTION : cette problématique n’est valide qu’au sein des packages. Dans un script,
ou dans les modules de même niveau qui ne sont pas intégrés au sein de packages, il
faut continuer d’utiliser des importations absolues (les importations relatives
ne fonctionnent pas).

#!html
<br clear=right>

Divers

  • Seul != est autorisé pour exprimer l’inégalité (et <> ne l’est plus).
  • Les classes suivent par défaut le « nouveau style ».
  • Les exceptions maisons doivent être des classes.
#!comment


  • Except et finally ne peuvent être mélangés qu'à partir de 2.5
  • With/as à partir de 2.6
  • exceptions maisons de type classes plutot que string à partir de 2.5 ?

#!html
<br clear=right>

Migrer de Python 2 à 3

  • Pourquoi rester en Python 2 ? Pour profiter des multiples bibliothèques disponibles.
  • Pourquoi migrer en Python 3 ? Pour profiter de ses simplifications et de ses optimisations :
  • fusion des types ‘int’ et ‘long’
  • a/b est la vraie division par défaut.
  • exec et print deviennent des fonctions.
  • itérateurs et vues plutôt que des listes (range(), map(), filter(), zip(), dict.keys(), dict.items(), dict.values()).
  • les chaînes sont en Unicode par défaut, ‘bytes’ remplace l’ancien type ‘str’
  • disparitions : `x`, l’opérateur <>, la méthode find() des chaînes, les fonctions apply(), buffer(), callable(), reduce()…
  • None et as deviennent des mots clé.
  • A noter : une commande (2to3) et une bibliothèque (lib2to3) sont supposées aider les programmeurs à migrer leur code.
  • A essayer dès 2.X
  • Utiliser les méthodes du type str au lieu du module string
  • A répéter dans tous vos fichiers :
  • from !future! import print_function
  • from !future! import division (2/3 retourne un float)
  • from !future! import absolute_import

References

#!comment


Pour mémoire, un exemple de mise en page avec du bleu à gauche et du jaune à droite en vis à vis.

{{{
#!div style="float:left;width:48%"

{{{
#!python

>>> titre = 'exemple'
>>> ligne = '='*len(titre)
>>> print(titre,ligne,sep='\n')
exemple
=======


}}}

#!div style="float:right;width:48%"


{{{
#!html
<pre style="margin-right:20px;border: 1px solid palegoldenrod;padding:4px;background-color:lightyellow">
>>> titre = 'exemple'
>>> ligne = '='*len(titre)
>>> print titre, '\n', ligne
exemple

=

</pre>


}}}

#!html
<br clear=right>

}}}

LangageEntreesSorties

[wiki: Entrées-sorties] [#license ©]

PageOutline

Formatage des affichages

  • La méthode str.format() permet de construire une chaîne de caractères complexe à partir d’une chaîne format et d’une collection de valeurs données en arguments.
  • Le format comprend des emplacements ou substituer les valeurs, délimités par des {...:...} .
  • A gauche du :, on ne met rien si on veut prendre les valeurs une par une, des numéros si on veut répéter ou inverser l’ordre de certaines valeurs, et des noms si les arguments sont nommés.
  • A droite du :, on donne un ensemble de caractères décrivant le format d’affichage de la valeur, à la façon de la fonction printf() du langage C.
>>> "Entiers : {:04d} {:o} {:X}".format(-2,8,15)
'Entiers : -002 10 F'


>>> "Flottants : {1:-E} {0:+2.3f} {1:-E}".format(4.5,0.000006)
'Flottants : 6.000000E-06 +4.500 6.000000E-06'

>>> "Avec noms : {ch:s} {val:d} {ch:s}".format(ch='texte',val=10)
'Avec noms : texte 10 texte'


Affichage et saisies

  • Instruction print
>>> titre = 'exemple'
>>> ligne = '='*len(titre)
>>> print(titre,ligne,sep='\n')
exemple


=

>>> print('This','is','an','exemple')
This is an exemple

>>> print('This','is','an','exemple',sep='-')
This-is-an-exemple

>>> print('1',end=) ; print('2',end=) ; print('3',end='') ;
123


  • Fonction input()
>>> res = input('texte : ')
texte : 3*2
>>> res
3*2
  • Avec eval()
>>> res = eval(input('expression : '))
expression : 3*2
>>> res
6

Fichiers

  • On ouvre un fichier par open(‘filename’, ‘mode’) et on le ferme par close(). Modes : ‘r’, ‘w’ et ‘a’. Quelques méthodes :
  • read() : lit tout le fichier dans une chaîne de caractères.
  • readline() lit une seule ligne.
  • readlines() lit tout le fichier dans une liste de chaînes.
  • write(‘string’) : écrit la chaine dans le fichier.
  • writelines(sequence) : écrit la séquence dans le fichier, en mettant bout à bout les éléments.
  • write.py :
#!python
noms = ['Yves', 'Jean', 'Dupont']
fichier = open('lesnoms.txt', 'w')
for nom in noms:
  fichier.write(nom+ '\n')
fichier.close()
  • read.py :
#!python
fichier = open('lesnoms.txt', 'r')
for ligne in fichier.readlines():
  print(ligne)
fichier.close()
#!comment


  • Pour le mode d'ouverture, on peut ajouter un '+' pour autoriser lecture et écriture, et un 'b' pour rpéciser que le fichier est binaire.
  • Rien ne sera écrit dans le fichier avant l’appel de la méthode close().

Exercices

1. Écrivez un programme qui demande son nom à l’utilisateur, et qui l’affiche ensuite à l’écran avec un message d’accueil.
1. Écrire un programme qui demande deux nombres à l’utilisateur, et qui affiche ensuite la somme, la différence et la multiplication de ces deux nombres.
1. Améliorez le programme précédent en ajoutant la division. Faites attention à prendre en compte le cas où le deuxième nombre est nul.
1. Écrire un programme qui récupère une liste de noms dans un fichier (un nom par ligne) et qui les trie par ordre alphabétique.

Références

© David Chamont, Laboratoire Leprince-Ringuet (LLR) / IN2P3 / CNRS, Ecole polytechnique / Université Paris-Saclaybr
© Ce(tte) œuvre est mise à disposition selon les termes de la Licence Creative Commons Attribution – Partage dans les Mêmes Conditions 4.0 International [=#license]


Attachments

LangageInterfaces

[wiki: Interface avec les autres langages de programmation]

PageOutline

A ETUDIER :
https://github.com/wjakob/pybind11

Utiliser l’ API C

#!comment
Est-ce que ca existe en Jython ?

Cette interface en langage C donne accès à tout le système Python, et permet d’écrire un module C qui peut être intégré dans un programme principal Python.

Imaginons que l’on veuille donner accès sous Python à la fonction system() du langage C.
On peut créer un module monsys, doté d’une méthode system(), à l’aide du fichier monsys.c suivant :

#!C
#include <Python.h>


static PyObject *
monsys_system(PyObject *self, PyObject *args)
{
const char *commande;
int res;

if (!PyArg_ParseTuple(args, "s", &commande))
return NULL;
res = system(commande);
return Py_BuildValue("i", res);
}

static PyMethodDef MonsysMethods[] = {
{ "system", monsys_system, METH_VARARGS, "Execute a shell command."},
{NULL, NULL, 0, NULL}
};

PyMODINIT_FUNC
initmonsys(void)
{
(void) Py_InitModule("monsys", MonsysMethods);
}


A l’inverse, on peut également, au sein d’un programme principal écrit en C, lancer et utiliser un interpréteur Python :

#!C
#include <Python.h>


int
main(int argc, char *argv[])
{
Py_SetProgramName(argv[0]); /* optional but recommended */
Py_Initialize();
PyRun_SimpleString("from time import time,ctime\n"
"print 'Today is',ctime(time())\n");
Py_Finalize();
return 0;
}


Utiliser le module ctypes

Ce module fournit des types de données compatible avec le C, ainsi que le moyen de charger des bibliothèques et d’appeler les fonctions qui s’y trouvent, le tout sans écrire la moindre ligne de C.

#!comment


Est-ce que ca existe en Jython ?
Qu'est-ce que ca ne peut pas faire, en comparaison d'une manipulation directe de l'API C ?


Exemple Linux ultra basique :

#!python


import ctypes

# charge la librairie
libc = ctypes.CDLL("libc.so.6")
print libc.printf

# appels de fonction sans argument
print libc.time(None)


Les seuls objets Python qui peuvent être directement passés à des appels de fonction via ctypes :

  • None : passé en tant que pointeur C NULL
  • entiers : passés en tant que type C int, quitte à tronquer la valeur.
  • chaines de caractères : passé en tant que char *
  • chaines de caractères unicode : passé en tant que wchar_t *

Sinon, ctypes définit un ensemble de types servant de passerelles :

ctypes typeC typePython type
c_bool_Boolbool (1)
c_charchar1-character string
c_wcharwchar_t1-character unicode string
c_bytecharint/long
c_ubyteunsigned charint/long
c_shortshortint/long
c_ushortunsigned shortint/long
c_intintint/long
c_uintunsigned intint/long
c_longlongint/long
c_ulongunsigned longint/long
c_longlong__int64 or long longint/long
c_ulonglongunsigned __int64 or unsigned long longint/long
c_floatfloatfloat
c_doubledoublefloat
c_longdoublelong doublefloat
c_char_pchar * (NUL terminated)string or None
c_wchar_pwchar_t * (NUL terminated)unicode or None
c_void_pvoid *int/long or None

Appeler une fonction de la libc :

#!python


>>> printf = libc.printf
>>> printf("Hello, %s\n", "World!")
Hello, World!
14
>>> printf("Hello, %S\n", u"World!")
Hello, World!
14
>>> printf("%d bottles of beer\n", 42)
42 bottles of beer
19
>>> printf("%f bottles of beer\n", 42.5)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
ArgumentError: argument 2: exceptions.TypeError: Don't know how to convert parameter 2
>>> printf("An int %d, a double %f\n", 1234, c_double(3.14))
An int 1234, a double 3.140000
31


Utiliser un outils d’interfacage automatique

Tout ce qui peut être interfacé avec du C peut donc être interfacé avec CPython, au prix de beaucoup d’effort pour écrire correctement le code qui fait l’interface. Des outils se proposent d’automatiser ces tâches :

Utiliser un interpréteur alternatif

De même, si vous souhaitez interfacer Python et Java, intéressez vous en priorité à Jython, l’implémentation de Python en langage Java.

Références

OutillageAnalyseurs

[wiki: Analyseurs de style]

PageOutline

Conventions usuelles

  • 4 espaces par niveau d’indentation.
  • lignes limitées à 79 caractères.
  • insérer une ligne vierge entre les définitions de fonctions et, classes, ainsi qu’entre les grandes articulations du code
  • mettre un espace de chaque côté des opérateurs, après une virgule ou deux points (mais pas avant), enfin, ne pas mettre d’espace après un signe ouvrant ou avant un signe fermant (c’est à dire (), {}, []) ;
  • utiliser des docstrings.
  • nommer les classes en !CamelCase, les fonctions, méthodes et variables en lower_case.

Convention avancées : PEP8.

PyChecker

PyLint

POP8 Checker

PyFlakes

Exercices

1. Essayez l’analyseur POP8 en ligne
1. Essayez d’installer PyLint et de l’utiliser à travers l’EDI Spider.

Références

LangageExceptions

[wiki: Exceptions]

#!comment


A TRAITER EVENTUELLEMENT A LA FIN : les
contexte et l'instruction "with"
http://effbot.org/zone/python-with-statement.htm


Exemple

#!python
# fichier math.py
...
def sqrt(x):
   if (x<0): raise ValueError
...
#!python
# fichier main.py
import math
try:
  while True:
    valeur = input('valeur dont vous voulez la racine : ')
    print math.sqrt(valeur)
except ValueError:
  print 'valeur interdite'

Mécanismes

  • Levées grâce au mot-clé raise et interceptées dans les blocs try-except.
  • Pour chaque bloc try, au moins un bloc except.
  • Trois formes possibles d’except :
  • avec nom de l’erreur,
  • avec tuple de plusieurs erreurs,
  • sans preciser le nom d’erreur(fortement déconseillé).
  • Le bloc else n’est exécuté que si aucun bloc except n’a été activé.
  • Le bloc finally est toujours exécuté, même en présence de continue/break/return.
  • L’utilisation de as donne accès à l’objet exception et à ses attributs.
  • Lorsqu’une exception n’est pas interceptée, l’interpréteur arrête le programme en cours et affiche la pile Traceback
#!python
try:
    num = int(raw_input('Enter a number: '))
except ValueError:
    print('You must enter a number.') 
else:
    print('You have entered a number. ')
finally:
    print('This text is always printed. ')

Cas d’utilisation

  • Gestion des erreurs
  • Signalisation d’évènements
  • Gestion de cas spéciaux
  • Actions de finalisation
  • Flots de contrôle inhabituels

Clauses

#!python
try:
  ...
except name:
  ...
except name, value:
  ...
except (nom1, nom2):
  ...
except (nom1, nom2), valeur:
  ...
except:
  ...
else:
  ...
finally:
  ...


raise nom # émet une exception
raise nom, données # ajoute des données complémentaires
raise # ré-émet l'exception courante
assert test # if debug
assert test, données #


== Exceptions standards

#!comment


  • NameError
  • IndexError
  • KeyError
  • AttributeError
  • TypeError
  • SyntaxError
  • AssertionError

L’interpréteur python lève des exceptions :

BaseException
 +-- SystemExit
 +-- KeyboardInterrupt
 +-- GeneratorExit
 +-- Exception
      +-- StopIteration
      +-- StandardError
      |    +-- BufferError
      |    +-- ArithmeticError
      |    |    +-- FloatingPointError
      |    |    +-- OverflowError
      |    |    +-- ZeroDivisionError
      |    +-- AssertionError
      |    +-- AttributeError
      |    +-- EnvironmentError
      |    |    +-- IOError
      |    |    +-- OSError
      |    |         +-- WindowsError (Windows)
      |    |         +-- VMSError (VMS)
      |    +-- EOFError
      |    +-- ImportError
      |    +-- LookupError
      |    |    +-- IndexError
      |    |    +-- KeyError
      |    +-- MemoryError
      |    +-- NameError
      |    |    +-- UnboundLocalError
      |    +-- ReferenceError
      |    +-- RuntimeError
      |    |    +-- NotImplementedError
      |    +-- SyntaxError
      |    |    +-- IndentationError
      |    |         +-- TabError
      |    +-- SystemError
      |    +-- TypeError
      |    +-- ValueError
      |         +-- UnicodeError
      |              +-- UnicodeDecodeError
      |              +-- UnicodeEncodeError
      |              +-- UnicodeTranslateError
      +-- Warning
           +-- DeprecationWarning
           +-- PendingDeprecationWarning
           +-- RuntimeWarning
           +-- SyntaxWarning
           +-- UserWarning
           +-- FutureWarning
	   +-- ImportWarning
	   +-- UnicodeWarning
	   +-- BytesWarning
#!comment


exception BaseException

The base class for all built-in exceptions. It is not meant to be directly inherited by user-defined classes (for that, use Exception). If str() or unicode() is called on an instance of this class, the representation of the argument(s) to the instance are returned, or the empty string when there were no arguments.

New in version 2.5.

args

The tuple of arguments given to the exception constructor. Some built-in exceptions (like IOError) expect a certain number of arguments and assign a special meaning to the elements of this tuple, while others are usually called only with a single string giving an error message.

exception Exception

All built-in, non-system-exiting exceptions are derived from this class. All user-defined exceptions should also be derived from this class.

Changed in version 2.5: Changed to inherit from BaseException.

exception StandardError

The base class for all built-in exceptions except StopIteration, GeneratorExit, KeyboardInterrupt and SystemExit. StandardError itself is derived from Exception.

exception ArithmeticError

The base class for those built-in exceptions that are raised for various arithmetic errors: OverflowError, ZeroDivisionError, FloatingPointError.

exception BufferError

Raised when a buffer related operation cannot be performed.

exception LookupError

The base class for the exceptions that are raised when a key or index used on a mapping or sequence is invalid: IndexError, KeyError. This can be raised directly by codecs.lookup().

exception EnvironmentError

The base class for exceptions that can occur outside the Python system: IOError, OSError. When exceptions of this type are created with a 2-tuple, the first item is available on the instance’s errno attribute (it is assumed to be an error number), and the second item is available on the strerror attribute (it is usually the associated error message). The tuple itself is also available on the args attribute.

New in version 1.5.2.

When an EnvironmentError exception is instantiated with a 3-tuple, the first two items are available as above, while the third item is available on the filename attribute. However, for backwards compatibility, the args attribute contains only a 2-tuple of the first two constructor arguments.

The filename attribute is None when this exception is created with other than 3 arguments. The errno and strerror attributes are also None when the instance was created with other than 2 or 3 arguments. In this last case, args contains the verbatim constructor arguments as a tuple.

The following exceptions are the exceptions that are actually raised.

exception AssertionError

Raised when an assert statement fails.

exception AttributeError

Raised when an attribute reference (see Attribute references) or assignment fails. (When an object does not support attribute references or attribute assignments at all, TypeError is raised.)

exception EOFError

Raised when one of the built-in functions (input() or raw_input()) hits an end-of-file condition (EOF) without reading any data. (N.B.: the file.read() and file.readline() methods return an empty string when they hit EOF.)

exception FloatingPointError

Raised when a floating point operation fails. This exception is always defined, but can only be raised when Python is configured with the --with-fpectl option, or the WANT_SIGFPE_HANDLER symbol is defined in the pyconfig.h file.

exception GeneratorExit

Raise when a generator‘s close() method is called. It directly inherits from BaseException instead of StandardError since it is technically not an error.

New in version 2.5.

Changed in version 2.6: Changed to inherit from BaseException.

exception IOError

Raised when an I/O operation (such as a print statement, the built-in open() function or a method of a file object) fails for an I/O-related reason, e.g., “file not found” or “disk full”.

This class is derived from EnvironmentError. See the discussion above for more information on exception instance attributes.

Changed in version 2.6: Changed socket.error to use this as a base class.

exception ImportError

Raised when an import statement fails to find the module definition or when a from ... import fails to find a name that is to be imported.

exception IndexError

Raised when a sequence subscript is out of range. (Slice indices are silently truncated to fall in the allowed range; if an index is not a plain integer, TypeError is raised.)

exception KeyError

Raised when a mapping (dictionary) key is not found in the set of existing keys.

exception KeyboardInterrupt

Raised when the user hits the interrupt key (normally Control-C or Delete). During execution, a check for interrupts is made regularly. Interrupts typed when a built-in function input() or raw_input() is waiting for input also raise this exception. The exception inherits from BaseException so as to not be accidentally caught by code that catches Exception and thus prevent the interpreter from exiting.

Changed in version 2.5: Changed to inherit from BaseException.

exception MemoryError

Raised when an operation runs out of memory but the situation may still be rescued (by deleting some objects). The associated value is a string indicating what kind of (internal) operation ran out of memory. Note that because of the underlying memory management architecture (C’s malloc() function), the interpreter may not always be able to completely recover from this situation; it nevertheless raises an exception so that a stack traceback can be printed, in case a run-away program was the cause.

exception NameError

Raised when a local or global name is not found. This applies only to unqualified names. The associated value is an error message that includes the name that could not be found.

exception NotImplementedError

This exception is derived from RuntimeError. In user defined base classes, abstract methods should raise this exception when they require derived classes to override the method.

New in version 1.5.2.

exception OSError

This exception is derived from EnvironmentError. It is raised when a function returns a system-related error (not for illegal argument types or other incidental errors). The errno attribute is a numeric error code from errno, and the strerror attribute is the corresponding string, as would be printed by the C function perror(). See the module errno, which contains names for the error codes defined by the underlying operating system.

For exceptions that involve a file system path (such as chdir() or unlink()), the exception instance will contain a third attribute, filename, which is the file name passed to the function.

New in version 1.5.2.

exception OverflowError

Raised when the result of an arithmetic operation is too large to be represented. This cannot occur for long integers (which would rather raise MemoryError than give up) and for most operations with plain integers, which return a long integer instead. Because of the lack of standardization of floating point exception handling in C, most floating point operations also aren’t checked.

exception ReferenceError

This exception is raised when a weak reference proxy, created by the weakref.proxy() function, is used to access an attribute of the referent after it has been garbage collected. For more information on weak references, see the weakref module.

New in version 2.2: Previously known as the weakref.ReferenceError exception.

exception RuntimeError

Raised when an error is detected that doesn’t fall in any of the other categories. The associated value is a string indicating what precisely went wrong. (This exception is mostly a relic from a previous version of the interpreter; it is not used very much any more.)

exception StopIteration

Raised by an iterator‘s next() method to signal that there are no further values. This is derived from Exception rather than StandardError, since this is not considered an error in its normal application.

New in version 2.2.

exception SyntaxError

Raised when the parser encounters a syntax error. This may occur in an import statement, in an exec statement, in a call to the built-in function eval() or input(), or when reading the initial script or standard input (also interactively).

Instances of this class have attributes filename, lineno, offset and text for easier access to the details. str() of the exception instance returns only the message.

exception IndentationError

Base class for syntax errors related to incorrect indentation. This is a subclass of SyntaxError.

exception TabError

Raised when indentation contains an inconsistent use of tabs and spaces. This is a subclass of IndentationError.

exception SystemError

Raised when the interpreter finds an internal error, but the situation does not look so serious to cause it to abandon all hope. The associated value is a string indicating what went wrong (in low-level terms).

You should report this to the author or maintainer of your Python interpreter. Be sure to report the version of the Python interpreter (sys.version; it is also printed at the start of an interactive Python session), the exact error message (the exception’s associated value) and if possible the source of the program that triggered the error.

exception SystemExit

This exception is raised by the sys.exit() function. When it is not handled, the Python interpreter exits; no stack traceback is printed. If the associated value is a plain integer, it specifies the system exit status (passed to C’s exit() function); if it is None, the exit status is zero; if it has another type (such as a string), the object’s value is printed and the exit status is one.

Instances have an attribute code which is set to the proposed exit status or error message (defaulting to None). Also, this exception derives directly from BaseException and not StandardError, since it is not technically an error.

A call to sys.exit() is translated into an exception so that clean-up handlers (finally clauses of try statements) can be executed, and so that a debugger can execute a script without running the risk of losing control. The os._exit() function can be used if it is absolutely positively necessary to exit immediately (for example, in the child process after a call to fork()).

The exception inherits from BaseException instead of StandardError or Exception so that it is not accidentally caught by code that catches Exception. This allows the exception to properly propagate up and cause the interpreter to exit.

Changed in version 2.5: Changed to inherit from BaseException.

exception TypeError

Raised when an operation or function is applied to an object of inappropriate type. The associated value is a string giving details about the type mismatch.

exception UnboundLocalError

Raised when a reference is made to a local variable in a function or method, but no value has been bound to that variable. This is a subclass of NameError.

New in version 2.0.

exception UnicodeError

Raised when a Unicode-related encoding or decoding error occurs. It is a subclass of ValueError.

New in version 2.0.

exception UnicodeEncodeError

Raised when a Unicode-related error occurs during encoding. It is a subclass of UnicodeError.

New in version 2.3.

exception UnicodeDecodeError

Raised when a Unicode-related error occurs during decoding. It is a subclass of UnicodeError.

New in version 2.3.

exception UnicodeTranslateError

Raised when a Unicode-related error occurs during translating. It is a subclass of UnicodeError.

New in version 2.3.

exception ValueError

Raised when a built-in operation or function receives an argument that has the right type but an inappropriate value, and the situation is not described by a more precise exception such as IndexError.

exception VMSError

Only available on VMS. Raised when a VMS-specific error occurs.

exception WindowsError

Raised when a Windows-specific error occurs or when the error number does not correspond to an errno value. The winerror and strerror values are created from the return values of the GetLastError() and FormatMessage() functions from the Windows Platform API. The errno value maps the winerror value to corresponding errno.h values. This is a subclass of OSError.

New in version 2.0.

Changed in version 2.5: Previous versions put the GetLastError() codes into errno.

exception ZeroDivisionError

Raised when the second argument of a division or modulo operation is zero. The associated value is a string indicating the type of the operands and the operation.

The following exceptions are used as warning categories; see the warnings module for more information.

exception Warning

Base class for warning categories.

exception UserWarning

Base class for warnings generated by user code.

exception DeprecationWarning

Base class for warnings about deprecated features.

exception PendingDeprecationWarning

Base class for warnings about features which will be deprecated in the future.

exception SyntaxWarning

Base class for warnings about dubious syntax

exception RuntimeWarning

Base class for warnings about dubious runtime behavior.

exception FutureWarning

Base class for warnings about constructs that will change semantically in the future.

exception ImportWarning

Base class for warnings about probable mistakes in module imports.

New in version 2.5.

exception UnicodeWarning

Base class for warnings related to Unicode.

New in version 2.5.


== Exemple de levée d’une exception prédéfinie

#!python


i=1
while i:
try:
i = int(raw_input('Choisissez un nombre de 1 a 10, 0 pour sortir : '))
if (i<0) or (i>10):
raise ValueError(i)
print 'Vous avez choisi :', i
except ValueError as v:
print 'Nombre inapproprie :', v


== Exemple de création d’un type d’exception personnalisé

#!python


class NombreInapproprie(Exception):
def init(self,val):
self.val = val
def str(self):
return 'Nombre inapproprie : %d'%self.val

def choisit_nombre():
i = int(raw_input('Choisissez un nombre de 1 a 10, 0 pour sortir : '))
if (i<0) or (i>10):
raise NombreInapproprie(i)
return i

if name=='main':
i=1
while i:
try:
i = choisit_nombre()
print i
except NombreInapproprie as ni:
print ni
except ValueError as ve:
print ve


Dans d’anciennes versions de Python 2, on pouvait lever des exceptions de type chaîne de caratères, entier, … ce n’est plus le cas. Il faut à présent que le type de l’exception levée soit une classe de style ancien, ou une classe utilisateur héritant de Exception.

== Pièges, trucs et astuces

  • Gare à « except: » qui attrape tout, y compris ce qu’on ne voudrait pas.
  • Gare à ne pas surutiliser « raise » pour émettre des exceptions que le système gère déjà très bien, par exemple la division par zéro.
  • Si vous faites « raise MaClasse », ce qui est autorisé, Python force la construction d’une instance, comme si vous aviez fait « raise MaClasse() ».

== Exercice

  • Dans votre classe servant à manipuler des fichiers, essayer de traiter par une levée d’exception le cas d’un appel à head() ou tail() ou le nombre de lignes demandées est supérieur au nombre de lignes disponibles dans le fichier lu. Mette les instructions raise dans la classe, et l’instruction try dans les tests.
  • documentation python 2
  • documentation python 3

Logging

[wiki: Journalisation]

PageOutline

La notion de « logging » consiste a tracer le fonctionnement d’un programme en envoyant
des messages sur différents canaux (console, fichier, mail, reseau,…), avec
différents niveaux d’importance et la possibilité de filtrer les messages en
fonction de ces niveaux. Python possège un module standard pour le faire : le
module logging.

== Exemple simple

5 niveaux de criticité sont prédéfinis par défaut :

  • CRITICAL (C) : erreur sévère au point de provoquer l’arrêt de l’application.
  • ERROR (E) : erreur non fatale au programme.
  • WARNING (W) : élément anormal, mais qui n’est pas nécessairement une erreur.
  • INFO (I) : information d’exécution normale.
  • DEBUG (D) : excessivement détaillé, pour le débogage.

Pour chaque canal de diffusion, on doit sélectionner un seuil de sensibilité
parmi les précédents, et le canal ne retiendra que les affichages d’un niveau
supérieur ou égal au seuil.

En général, le programmeur fait en sorte que le seuil puisse être
ajusté par l’utilisateur au lancement de l’application.

Exemple simple ou tous les messages sont conservés dans
un fichier :

#!python
import logging


logging.basicConfig(filename='essai.log',level=logging.DEBUG,
format='%(asctime)s -- %(name)s -- %(levelname)s -- %(message)s')

logging.debug('Debug message')
logging.info('Info message')
logging.warning('Warning message')
logging.error('Error message')
logging.critical('Critical message')


Pour personnaliser le format d’affichage, l’ensemble des variables
disponibles est ici.

== Enregistreurs (logger), gestionnaires (handler) et formatteurs (formatter)

Dans l’exemple simpliste ci-dessus, même si ils n’apparaissent pas,
interviennents en réalité un enregistreur principal (logger),
nommé «  » (ou « root »), et un gestionnaire (handler) chargé de la
transmission des messages au fichier.

Chaque canal de diffusion est contrôlé par un « gestionnaire » (handler),
et un enregistreur peut diffuser simultanément sur plusieurs canaux,
chacun avec son propre gestionnaire, son propre seuil de sensibilité et
son formatteur (Formatter) spécifique.

Ci-dessous, un exemple qui enregistre toute l’information dans un fichier,
et l’information « non debug » sur la console.

#!python
import logging


console_handler = logging.StreamHandler()
console_handler.setFormatter(logging.Formatter())
console_handler.setLevel(logging.INFO)

file_handler = logging.FileHandler(file[:-3]+".log", mode="w", encoding="utf-8")
file_handler.setFormatter(logging.Formatter("%(asctime)s :: %(name)s :: %(levelname)s :: %(message)s"))
file_handler.setLevel(logging.DEBUG)

logger = logging.getLogger("main")
logger.setLevel(logging.DEBUG)
logger.addHandler(console_handler)
logger.addHandler(file_handler)

logger.info('================')
logger.debug ('Debug message')
logger.info ('Info message')
logger.warning ('Warning message')
logger.error ('Error message')
logger.critical('Critical message')


== Utiliser un même enregistreur dans plusieurs modules

La liste de tous les enregistreurs créés, avec leurs noms, est
centralisée dans le module logging, et vous pouvez récupérez
ces enregistreurs depuis n’importe quel module, par le biais
d’un appel à logging.getLogger(<le-nom>) avec le nom
approprié.

Si vous voulez utilisez le même enregistreur partout, utilisez
l’enregistreur racine, de nom «  », dans tous vos modules. Un
des modules, ou le programme principal, étant chargé de
configurer correctement cet enregistreur, si possible
précocement, avant qu’il soit utilisé par quiconque.

== Bonnes pratiques

Préférez log.debug('My debug message %s',myobject) à log.debug('My debug message %s' % myobject). Dans le premier cas, la transformation de myobject) en chaine de caractères, qui peut passer par des opérations couteuses, n’est appliquée que si le seuil logging.DEBUG est actif et l’affichage nécessaire.

Références