.. $Id: documentation.rst.in 14117 2011-05-11 08:12:37Z ycadour $

.. _Python: http://www.python.org

.. index:: syntaxe

###################
Syntaxe du language
###################

La syntaxe du langage python est connue pour être

 - Simple
 - Concise
 - Efficace

.. index:: indentation

=============
L'indentation
=============

Une des caractéristiques du langage Python_ est l'utilisation des indentations comme structuration des programmes.

Exemples:

    >>> word = 'bonjour'
    >>> for letter in word:
    ...     print(letter)
    ... 
    b
    o
    n
    j
    o
    u
    r

L'interpréteur détermine le nombre d'espace au début de chaque ligne et en déduit le niveau d'indentation.
Une mauvaise indentation peut provoquer une erreur syntaxique.

::

    >>> for letter in 'Bonjour':
    ... print(letter)
      File "<stdin>", line 2
        print(letter)
            ^
    IndentationError: expected an indented block

Par convention on utilise 4 caractères d'espacement pour une indentation.

**Cette caractéristique du langage permet d'obtenir un code forcément bien indenté puisque l'indentation fait partie intégrante du langage.**

.. index:: commentaires

================
Les commentaires
================

Les commentaires sont préfixés par le caractère dièse '#' et peuvent être placés en fin de ligne ou prendre une ligne complète.

::

    >>> a = 'Bonjour' #Ceci est une affectation variable
    >>> # Maintenant j'affiche la variable
    ... print(a)
    Bonjour

.. index:: types

====================
Les différents types
====================

--------------------
Les types numériques
--------------------

Il en existe 3 types:

 - Les entiers (simple ou long)
 - Les valeurs à virgule flottante
 - Les nombres complexes

.. index:: int, entier

Les entiers
###########

- Les entiers sont des nombres qui s'étendent sur une machine 32 bits entre les valeurs -2e31+1 et 2e31-1, soit entre -2147483647 et 2147483647.
- Pour obtenir un nombre négatif on le préfixe du signe '-'

Les différentes bases:

- La forme décimale commence par un chiffre de 1 à 9 suivi de chiffre de 0 à 9.
- La base octale commence par '0' suivi de chiffres de 0 à 7.
- La base hexadécimale commence par '0x' suivi de chiffres 0 à 9 et de lettres de A à F.


Les entiers longs

- Les entiers longs sont eux limités uniquement par la capacité mémoire de la machine.
- Ils sont représentés de la même manière que les entiers mais sont suffixés de la lettre L.
- Depuis la version de 2.4 un nombre entier est automatiqument transtypé si il dépasse la plage autorisée.

::

    >>> x = 1
    >>> type(x)
    <type 'int'>
    >>> x = 10000000000000000000000000000000000000000
    >>> type(x)
    <type 'long'>

.. index:: float, flottant

Les flottants
#############

- Les flottants permettent de représenter des nombres réels.
- La partie entière est séparée de la partie fractionnelle par un '.'

::

    >>> x = 1.0
    >>> type(x)
    <type 'float'>
    >>> x = 1.
    >>> x = 0.1
    >>> x = .1
    >>> x = -09.02
    >>> x = -9.02

.. index:: complexe

Les nombres complexes
#####################

::

    >>> a = 2 + 1j
    >>> b = 1 + 2j
    >>> a+b
    (3+3j)
    >>> a.imag
    1.0
    >>> a.real
    2.0
    >>> a.conjugate()
    (2-1j)


.. index:: séquence

-------------
Les séquences
-------------
 
**Une séquence est une collection ordonnée d'éléments indexés par des nombres positifs.**
Les index varient de 0 à n-1 pour une séquence de n éléments.

Pour accéder à l'élement qui se trouve en position i on opére de la manière suivante:

**sequence[i-1]**

+-------+-------+-------+-----------+-------+-------+
| el1   | el2   |       | **eli**   |       |  eln  |
+=======+=======+=======+===========+=======+=======+
| 0     | 1     |       | **i-1**   |       |   n-1 |
+-------+-------+-------+-----------+-------+-------+

On peut utiliser des nombres négatifs en les faisant varier de -1 à -n :

**sequence[-2]**

+-------+-------+-------+-----------+-------+
| el1   | el2   |       | **eln-1** | eln   |
+=======+=======+=======+===========+=======+
| -n    | -n+1  |       | **-2**    | -1    |
+-------+-------+-------+-----------+-------+

Les séquences peuvent être coupées en tranches qui forment alors des sous séquences. sequence[i,j] forme la sequence de l'élement i inclus jusqu'à l'élément j exclu :

**sequence[1:3]**

+-------+---------+---------+---------+---------+---------+
| el1   | **el2** | **el3** | el4     |         | eln     |
+=======+=========+=========+=========+=========+=========+
| 0     | **1**   | **2**   | 3       |         |         |
+-------+---------+---------+---------+---------+---------+

**sequence[0:-1]**

+---------+---------+---------+---------+---------+---------+---------+
| **el1** | **el2** | **el3** | **el4** |         |**eln-1**| eln     |
+=========+=========+=========+=========+=========+=========+=========+
| **0**   | **1**   | **2**   | **3**   |         | **-2**  | -1      |
+---------+---------+---------+---------+---------+---------+---------+


- sequence[:-1] <=> sequence[0:-1]
- sequence[1:] <=> sequence[1:n]

Il existe un troisième élement qui permet de faire varier le pas.

**sequence[0:-1:2]**

+-------+---------+---------+---------+---------+
|**el1**| el2     | **el3** | el4     |         |
+=======+=========+=========+=========+=========+
|**0**  | 1       | **2**   | 3       |         |
+-------+---------+---------+---------+---------+

sequence[::-1] => inverse l'ordre de la séquence

Quelques primitives qui s'appliquent sur les séquences:

- *len()* : retourne le nombre d'élements de la séquence
- *min()*, *max()* : renvoie respectivement l'élement à valeur minimale et maximale de la séquence
- *sum()* : renvoie la somme des élements lorsque ceux ci sont additionnables.

En python il existe 4 types de séquences:

- Les strings
- Les unicode
- Les listes
- Les tuples

Il existe 2 grandes familles de séquences, les **séquences immuables** (string, unicode et tuple) et les **séquences modifiables** (liste).

.. index:: string, chaîne de caractères

Les bytes (ex string python 2)
###############################

Les *bytes* sont des valeurs alphanumériques, elles sont entourées de guillemets simples ou doubles ou de 3 guillemets simples ou doubles et préfixées par un b.
Elles sont toujours encodées.
::

    >>> a = b'hello'
    >>> b = b"hello"
    >>> c = b'''hello'''
    >>> d = b"""hello"""
    
Un byte est une **séquence ordonnée** d'éléments.

**Un byte n'est plus modifiable une fois instanciée**.

Les *byte* sont des séquences de caractères. Par défaut, chaque caractère est codé sur 8 bits ce qui correspond à des valeurs de 0 à 255.
Les valeurs de 0 à 127 sont les caractères de la tables ASCII ceux de 128 à 255 les caractères de la table ASCII étendue.

**Il n'existe pas en python de type caractère**, un caractère est un byte de longueur 1.

En python 2, les strings sont portés par l'ancienne classe: *les strings*.

Quelques primitives du langage sur les strings

::

    >>> chr(120)
    'x'
    >>> ord(b'x')
    120
    
Les bytes sont des séquences, les différents éléments sont accessibles comme décrit plus haut:

::

    >>> mot = b'hello'
    >>> mot[1]
    '101'

Les bytes sont des séquences immuables, leurs valeurs ne sont donc pas modifiables.

::

    >>> mot[1] = b'a'
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: 'bytes' object does not support item assignment
    
Méthodes sur les bytes
========================

::

    >>> mot = b'Hello'
    >>> dir(mot)
    ['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__',
    '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__',
    '__getslice__', '__gt__', '__hash__', '__init__', '__le__', '__len__',
    '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__',
    '__reduce_ex__', '__repr__', '__rmod__', '__rmul__','__setattr__',
     '__sizeof__', '__str__', '__subclasshook__', '_formatter_field_name_split',
     'capitalize', 'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs',
     'find', 'format', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace',
     'istitle','isupper', 'join', 'ljust', 'lower', 'lstrip', 'partition',
     'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip',
     'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title',
     'translate', 'upper', 'zfill']
     
**Exercice:Créer une string et essayer quelques méthodes.** Voir en particulier les méthodes *split* et *join*.

.. index:: unicode

Les strings (ex unicode)
#######################

Le type *str* fonctionne de la même façon mais sur une plage de 32 bits. Ils sont standards en python 3.x. (format encodage utilisé par défaut).

    >>> unichr(16000)
    u'\u3e80'
    >>> print(unichr(16000))
    㺀
    >>> ord('€')
    8364

La conversion entre *bytes* et *strings** est possible grâce aux méthodes encode et décode, puique la relation ne peut être bijective on utilise un codec qui permet d'établir la correspondance entre les deux.

::

    >>> encode = 'é'.encode('ISO-8859-15')
    >>> print(encode)
    é
    >>> decode='é'.encode('ISO-8859-15').decode('ISO-8859-15')
    >>> print(decode)
    é

Formatage des chaines de caractères (strings ou bytes)

::

    >>> firstname = 'John'
    >>> lastname = 'Cleese'
    >>> print("Hello {}".format(firstname))
    Hello John
    >>> print("Hello {0} {1}".format(firstname, lastname))
    Hello John Cleese


Il existe certaines expression pour modifier la valeur de l'argument. Exemple, pour les float, la syntaxe est .[P]f où P est un paramètre optionnel qui précise la précion utilisée.

::

    >>> pi = 3.14141592654
    >>> print ("pi vaut {:.2f}".format(pi))
    >>> print ("pi vaut {0:.2f}".format(pi))

::

    >>> pi = 3.14141592654
    >>> print ("pi vaut {:.2f}".format(pi))
    >>> print ("pi vaut {0:.2f}".format(pi))
    
D'autres méthodes de formatage existent, mais elles sont à proscrire:

::

    >>> firstname = 'John'
    >>> lastname = 'Cleese'
    >>> print("Hello %s" % firstname)
    Hello John
    >>> print("Hello %s %s" % (firstname,lastname))
    Hello John Cleese
    



*TODO: utiliser la méthode format  avec quelques exemples* 

.. index:: tuple

Les tuples
##########

**Les tuples sont des séquences qui contiennent des éléments qui peuvent être hétérogènes.**
Un tuple est encadré par des parenthèses et chaque élément est séparé par une virgule.
**Une fois créé il est impossible de modifier sa valeur.**

::

    >>> actors = ('John Cleese', 'Terry Gilliam', 'Michael Palin')
    >>> heterogene = ('John Cleese', 2, u'Terry Gilliam')
    >>> len(actors)
    3
    >>> actors[1]
    'Terry Gilliam'
    
    >>> actors[1] = 'Terry Jones'
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: 'tuple' object does not support item assignment
    

.. index:: list

Les listes
##########

**Les listes sont des séquences d'élements qui peuvent être hétérogènes et dont la valeur peut être modifiée après sa création.**

Une liste est encadrée par des crochets et chaque élément est séparé par une virgule.

::

    >>> liste_vide = []
    >>> actors = ['John Cleese']
    >>> len(actors)
    1

Voici quelques méthodes qui s'appliquent aux listes.

::

    >>> dir(actors)
    ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__delslice__', 
     '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__',
     '__getslice__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__',
     '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__',
     '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__',
     '__setattr__', '__setitem__', '__setslice__', '__sizeof__', '__str__','__subclasshook__',
     'append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
    >>> actors.append('Terry Gilliam')
    >>> actors
    ['John Cleese', 'Terry Gilliam']
    >>> new_actors = ['Michael Palin', 'Terry Jones']
    >>> actors.extend(new_actors)
    >>> actors
    ['John Cleese', 'Terry Gilliam', 'Michael Palin', 'Terry Jones']
    >>> actors.insert(2, 'Eric Idle')
    >>> actors
    ['John Cleese', 'Terry Gilliam', 'Eric Idle', 'Michael Palin', 'Terry Jones']
    >>> actors.remove('John Cleese')
    >>> actors
    ['Terry Gilliam', 'Eric Idle', 'Michael Palin', 'Terry Jones']
    >>> actors.pop(2)
    'Michael Palin'
    >>> actors
    ['Terry Gilliam', 'Eric Idle', 'Terry Jones']
    >>> actors.index('Terry Jones')
    2
    >>> actors.append(actors[2])
    >>> actors
    ['Terry Gilliam', 'Eric Idle', 'Terry Jones', 'Terry Jones']
    >>> actors.count('Terry Jones')
    2
    >>> actors.sort()
    >>> actors
    ['Eric Idle', 'Terry Gilliam', 'Terry Jones', 'Terry Jones']
    >>> actors.reverse()
    >>> actors
    ['Terry Jones', 'Terry Jones', 'Terry Gilliam', 'Eric Idle']
    
**Exercice: Créer une liste et essayer certaines méthodes**

    
.. index:: dict, dictionnaire
-----------------
Les dictionnaires
-----------------

Le mapping, appelé dictionnaire, est une collection d'éléments qui sont identifiés par des clefs uniques.

- Un dictionnaire n'est pas ordonné.
- Les clefs doivent être des objets immuables (chaines de caractère, entier, flottant...)
- Les élements peuvent être hétérogènes

Un dictionnaire est encadrée par des accolades, chaque élement est séparé par une virgule,  Chaque élement est préfixé par sa clef suivi de ':'.

::

    >>> dico_vide = {}
    >>> cleese = {'firstname':'John', 'lastname':'Cleese', 'year_of_birth':1939, 'movies':['Monty Python, la vie de Brian', 'Un poisson nommé wanda']}
    >>> len(cleese)
    4
    >>> cleese['firstname']
    'John'
    
Voici quelques méthodes des dictionnaires

    >>> a = {}
    >>> dir(a)
    >>> ['__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__',
     '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__',
      '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', 
      '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']

Autres exemples de création

    >>> dict(sape=4139, guido=4127, jack=4098)
    {'sape': 4139, 'jack': 4098, 'guido': 4127}
    >>> dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])
    {'sape': 4139, 'jack': 4098, 'guido': 4127}
**Exercice: Créer un dictionnaire et essayer certaines méthodes**


.. index:: set, ensemble
------------------------
Les ensembles (type set)
------------------------

TODO: un conteneur d'objets uniques avec des méthodes permettant de faire des calculs d'intersection, d'union, etc...

Un ensemble est encadré par des accolades et chaque élément est séparé par une virgule.

::

    >>> ensemble = {} #dictionnaire
    >>> ensemble = {'John Cleese','Terry Gilliam'} # type set
    >>> len(ensemble)
    2
    >>> ensemble.update({'John Cleese'})
    >>> len(ensemble)
    2    
    
    
----
None
----

Type à valeur unique qui ne représente une absence de valeur.

.. index:: booléen

------------
Les booleans
------------

Représentés par 'True' ou 'False'

Tout les types de valeur peuvent être interprétés de manière booléénne

 +-------------+--------------+---------------------+
 | type        | False        | True                |
 +=============+==============+=====================+
 | int         | 0            | les autres valeurs  |
 +-------------+--------------+---------------------+
 | float       | .0           | les autres valeurs  |
 +-------------+--------------+---------------------+
 | list        | []           | les listes non vides|
 +-------------+--------------+---------------------+
 | tuple       | ()           | les tuples non vides|
 +-------------+--------------+---------------------+
 | dict        | {}           | les dicts non vides |
 +-------------+--------------+---------------------+
 | noneType    | None         |        X            |
 +-------------+--------------+---------------------+
 
------------------
Synthèse des types
------------------

 +-------------+-----------------+---------------------+---------------------+
 | type        | exemple         | sequence            | modifiable          |
 +=============+=================+=====================+=====================+
 | int         | 1               | NON                 | NON                 |
 +-------------+-----------------+---------------------+---------------------+
 | float       | 1.0             | NON                 | NON                 |
 +-------------+-----------------+---------------------+---------------------+
 | complex     | 1+1j            | NON                 | NON                 |
 +-------------+-----------------+---------------------+---------------------+
 | unicode     | 'Hello'         | OUI                 | NON                 |
 +-------------+-----------------+---------------------+---------------------+
 | byte        | b'Hello'        | OUI                 | NON                 |
 +-------------+-----------------+---------------------+---------------------+
 | tuple       | ('string',1)    | OUI                 | NON                 |
 +-------------+-----------------+---------------------+---------------------+
 | list        | ['string',1]    | OUI                 | OUI                 |
 +-------------+-----------------+---------------------+---------------------+
 | dict        | {'key':'valeur'}| NON                 | OUI                 |
 +-------------+-----------------+---------------------+---------------------+

-----------
Transtypage
-----------

 +-------------+-----------------+-------------------------------------------+
 | primitive   | exemple         | description                               |
 +=============+=================+===========================================+
 | str(el)     | str(1) => '1'   | retourne l'élement sous forme de string   |
 +-------------+-----------------+-------------------------------------------+
 | int(el)     | int('1') => 1   | retourne l'élement sous forme d'entier    |
 +-------------+-----------------+-------------------------------------------+
 | float(el)   | float('1')=>1.0 | retourne l'élement sous forme de float    |
 +-------------+-----------------+-------------------------------------------+
 | list(el)    | list('1')=>['1']| retourne l'élement sous forme de liste    |
 +-------------+-----------------+-------------------------------------------+
 | tuple(el)   | tuple([1])=>(1,)| retourne l'élement sous forme de tuple    |
 +-------------+-----------------+-------------------------------------------+

.. index:: opérateurs

==============
Les opérateurs
==============


----------------------
Les opérateurs de base
----------------------

Addition, soustraction, multiplication, division

::

    >>> 2+3
    5
    >>> 3-5
    -2
    >>> 2*7
    14
    >>> 'hello'*5
    'hellohellohellohellohello'
    >>> 'hello' + ' ' + 'world'
    'hello world'
    >>> 1/6
    0
    >>> 1.0/6
    0.16666666666666666

----------------
Autre opérateurs
----------------

Modulo
######

opérateur %

::

    >>> 10 % 3
    1

Négation
########

opérateur -

::

    >>> a = 10
    >>> -a
    -10

Puissance
#########

opérateur **

::

    >>> 2 ** 8
    256

Appartenance
############

opérateur *in*

S'applique à toutes les séquences

::

    >>> 'y' in 'Terry'
    True
    >>> 1 in [0,1,2,3,4]
    True
    
Opérateurs de comparaison
#########################

- < : inférieur strictement
- > : supérieur strictement
- <= : inférieur ou égal
- >= : supérieur ou égal
- == : égal
- != : différent
- is : est
- is not : n'est pas

Une comparaison travaille sur deux objets et renvoie un résultat **booléen**.

Exemple de comparaison de deux strings égales::
Les strings sont immuables, l'affectation mémoire des deux objets est identique::

    >>> a = 'Hello'
    >>> b = 'Hello'
    >>> id(a)
    39756736
    >>> id(b)
    39756736
    >>> a is b
    True

=============================
Les structures conditionnelles
=============================


Les structures conditionnelles sont des regroupements de lignes délimitées par un niveau d'indentation et dont le contenu est exécuté en fonction d'une ou plusieurs conditions.


.. index:: if

----------------
L'instruction if
----------------

Syntaxe::

if condition:
    bloc de lignes
else:
    bloc de lignes


Exemples::

    >>> actors = ['Terry Jones', 'Terry Gilliam', 'Eric Idle']
    >>> if 'Terry Jones' in actors:
        ... print('Terry Jones est dans les acteurs')
    ... else:
    ...     print('Terry Jones n\'est pas dans les acteurs')
    ... 
    Terry Jones est dans les acteurs
    
    >>> if 'Terry Jones' or 'Eric Idle' in actors:
    ...     print('Il y a Terry Jones ou Eric Idle')
    ... 
    Il y a Terry Jones ou Eric Idle
    
    >>> if 'John Clesse' in actors:
    ...     print('Il y a Terry Jones')
    ... elif 'Terry Gilliam' in actors:
    ...     print('Il y a Terry Gilliam')
    ... else:
    ...     print('Il n\'y a ni Terry Gilliam ni Terry Jones')
    ... 
    Il y a Terry Gilliam
    

.. index:: for..in

---------------------
L'instruction for..in
---------------------

Syntaxe::

for variable in sequence:
    bloc de lignes
else:
    bloc de lignes
    
Exemples::

    >>> for actor in actors:
    ...     print(actor)
    ... 
    Terry Jones
    Terry Gilliam
    Eric Idle
    
    >>> for letter in actors[0]:
    ...     print(letter)
    ... else:
    ...     print('fini')
    ... 
    T
    e
    r
    r
    y
     
    J
    o
    n
    e
    s
    fini

Deux instructions permettent d'influer sur le déroulement de la boucle:

- *continue* interrompt l'execution de la boucle pour l'élément en cours et passe à l'élement suivant.
- *break* interrompt l'execution de la boucle et n'exécute pas l'instruction else.

::

    >>> for letter in actors[0]:
    ...     if letter=='e':
    ...         continue
    ...     print(letter)
    ... 
    T
    r
    r
    y
     
    J
    o
    n
    s
    
    >>> for actor in actors:
    ...     print(actor)
    ...     if actor == 'Terry Gilliam':
    ...         break
    ... 
    Terry Jones
    Terry Gilliam

.. index:: while

-------------------
L'instruction while
-------------------

L'instruction *while* permet d'exécuter un bloc de lignes tant qu'une expression est vérifiée. Si l'expression n'est plus vraie l'instruction estlse est exécutée ci celle ci existe et la boucle s'arrête.

Remarque : Les instructions *continue* et *break* peuvent également s'utiliser avec *while*

Syntaxe::

while condition:
    bloc de lignes
else:
    bloc de lignes

Exemple::

    >>> i = 1
    >>> while i < 100:
    ...    i += i
    ...    print i
    ... 
    2
    4
    8
    16
    32
    64
    128
    
.. index:: list comprehensions

=======================
Les list comprehensions
=======================

Les lists comprehensions donnent un moyen concis d'appliquer une fonction sur chaque élément d'une liste afin d'en produire une nouvelle.

Voir http://docs.python.org/tutorial/datastructures.html#list-comprehensions

Exemples:

::

    >>> nombres = [1,3,8,9,7,32,89,42]
    >>> # retourner sous forme de liste chacun des nombres au carré
    >>> [nombre*nombre for nombre in nombres]
    [1, 9, 64, 81, 49, 1024, 7921, 1764]

    >>> nombres = [1,3,8,9,7,32,89,42]
    >>> # retourner sous forme de liste les nombres pairs
    >>> [nombre for nombre in nombres if nombre%2==0]
    [8, 32, 42]

.. index:: dict comprehensions

=======================
Les dict comprehensions
=======================

Les dict comprehensions donnent un moyen concis de créer un dictionnaire  à partir d'une itération.


Exemples:

::


    >>> {x: x**2 for x in (2, 4, 6)}
    {2: 4, 4: 16, 6: 36}


.. index:: exceptions

==========
Exceptions
==========

Une exception est lévée lorsque les conditions d'execution du programme ne sont pas respectées.

L'exception la plus emblématique est la division par zéro

::
    
    >>> 1/0
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ZeroDivisionError: integer division or modulo by zero

.. index:: try..except..else

-----------------
try..except..else
-----------------

Lorsqu'une exception est levée il est possible de la stopper en interceptant l'erreur.

syntaxe

::

    try:
        bloc de code surveillé
    except:
        bloc de code exécuté si l'exception est levée

::

    >>> def division(a,b):
    ...     try:
    ...         return a/b
    ...     except:
    ...         return 'infini'
    ... 
    >>> division(4,0)
    'infini'
    >>> division('allo',0)
    'infini'

Il est fortement conseillé de spécifier l'exception afin de ne pas masquer silencieusement tous les types d'erreur qui pourrait intervenir.

::

    >>> def division(a,b):
    ...     try:
    ...         return a/b
    ...     except ZeroDivisionError:
    ...         return 'infini'
    ... 
    >>> division(4,0)
    'infini'
    >>> division('allo',0)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "<stdin>", line 3, in division
    TypeError: unsupported operand type(s) for /: 'str' and 'int'

Il est possible d'associer plusieurs exceptions à la suite.

    >>> def division(a,b):
    ...     try:
    ...         return a/b
    ...     except ZeroDivisionError:
    ...         return 'infini'
    ...     except TypeError:
    ...         return 'veuillez rentrer des nombres'

Le bloc *else* est exécuté à la fin uniquement si il n'y a aucune erreur.

.. index:: try..finally

------------
try..finally
------------

syntaxe

::

    try:
        bloc de code surveillé
    finally:
        code toujours exécuté (y compris si raise ou return dans le bloc surveillé).

-------------------
quelques exceptions
-------------------

- AttributeError
- ImportError
- IndentationError
- IndexError
- KeyError
- MemoryError
- SyntaxError
- TypeError
- ZeroDivisionError


--------------------------------
Exercice
--------------------------------

Compléter le script "tests_exercices.py" proposé dans l'archive.

