Aller au contenu

Python

Python logo

Entête de script Python

En général, l'entête d'un script Python doit comporter :

  • la version de Python utilisée;
  • l'encodage du fichier.

Exemple d'entête pour un script Python 3

1
2
#!/usr/bin/env python3
# -*- coding: utf_8 -*-

Exemple d'entête pour un script Python 2

1
2
#!/usr/bin/env python2
# -*- coding: utf_8 -*-

Attention

La déclaration #!/usr/bin/env python est ambiguë. En effet elle peut faire référence à Python 2.x ou Python 3.x en fonction des versions de Python installées sur le système.

Ressources

Encodage

Unicode

Dans un texte, les mots et les phrases sont créés à partir de caractères. La lettre latine « á », l’idéogramme chinois « 請 » ou le caractère Devanagari « ह » sont des exemples de caractères.

Les caractères sont regroupés dans un registre de caractères (également appelé répertoire), appelé ensuite registre de caractères codés lorsqu'un chiffre précis est attribué à chaque caractère, nommé point de code. Ces points de code sont représentés dans l’ordinateur par un octet ou plus.

L’encodage de caractères (ou encoding) est la clé qui structure les points de code en octets dans la mémoire de l’ordinateur, puis lit les octets à nouveau en points de code.

Par exemple, le caractère « É » a pour point de code U+00C9 dans la norme Unicode. Il est encodé selon le jeu de caractères UTF-8 sur deux octets : C389.

UTF-8 est compatible avec le jeu de caractère ASCII. Par exemple, le caractère « j » a pour point de code U+006A dans la norme Unicode. Il est encodé selon le jeu de caractères ASCII sur un octet : 6A. Selon le jeu de caractères UTF-8, il est également encodé sur un octet : 6A.

Pour convertir un point de code Unicode (UCS code number) en sa représentation selon le jeu de caractère UTF-8, voir la très bonne explication du manuel Linux : utf8(7) - Linux man page.

Important

Utiliser UTF-8. Partout. Tout le temps.
Décoder systématiquement toutes les entrées du programme.
Encoder systématiquement toutes les sorties du programme.

Code source

L'encodage par défaut pour le code source Python 2 est ASCII.

En revanche, l'encodage par défaut pour le code source Python 3 est UTF-8, l'implémentation la plus célèbre d'Unicode.

Pour éviter les erreurs (particulièrement en Python 2), il est nécessaire de déclarer l'encodage utilisé dans le fichier source, en début de programme :

1
# -*- coding: utf_8 -*-

Le type String

En Python 2.7, les chaînes de caractères (<type 'str'>) sont des séquences d'octets. Il faut préfixer une chaîne de caractères par un u pour obtenir une chaîne Unicode (<type 'unicode'>).

Depuis Python 3, les chaînes de caractères (<class 'str'>) sont des chaînes Unicode. Il faut préfixer une chaîne de caractères par un b pour obtenir une séquences d'octets (<class 'bytes'>).

Le type String en Python 3

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
>>> chaîne_unicode = "éléphant" # encodage UTF-8 par défaut
>>> chaîne_unicode
'éléphant'                      # chaîne de caractères Unicode
>>> type(chaîne_unicode)
<class 'str'>
>>> print(chaîne_unicode)
éléphant                        # chaîne de caractères Unicode

>>> chaîne_octets = chaîne_unicode.encode("utf_8")
>>> chaîne_octets
b'\xc3\xa9l\xc3\xa9phant'       # séquences d'octets
>>> type(chaîne_octets)
<class 'bytes'>
>>> print(chaîne_octets)
b'\xc3\xa9l\xc3\xa9phant'       # séquences d'octets

>>> print(chaîne_octets.decode("utf_8"))
éléphant                        # chaîne de caractères Unicode bien décodée
>>> print(chaîne_octets.decode("ascii", "replace"))
��l��phant                      # chaîne de caractères Unicode mal décodée

Le type String en Python 2.7

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
>>> chaine_unicode = u"éléphant"
>>> chaine_unicode
u'\xe9l\xe9phant'               # chaîne de caractères Unicode
>>> type(chaine_unicode)
<type 'unicode'>
>>> print(chaine_unicode)
éléphant                        # chaîne de caractères Unicode

>>> chaine_octets = chaine_unicode.encode("utf_8")
>>> chaine_octets
'\xc3\xa9l\xc3\xa9phant'        # séquences d'octets
>>> type(chaine_octets)
<type 'str'>
>>> print(chaine_octets)
éléphant                        # attention, séquences d'octets !

>>> print(chaine_octets.decode("utf_8"))
éléphant                        # chaîne de caractères Unicode bien décodée
>>> print(chaine_octets.decode("ascii", "replace"))
��l��phant                      # chaîne de caractères Unicode mal décodée

En Python 2.7, il est possible de s'affranchir du prefixe u pour déclarer une chaîne Unicode. Attention, le principe d'encodage / décodage reste inchangé :

1
$ python2.7
1
2
3
4
>>> from __future__ import unicode_literals
>>> chaine_unicode = "éléphant"
>>> chaine_unicode
u'\xe9l\xe9phant'               # chaîne de caractères Unicode

Résumé du type String

Python 3 Python 2.7 Python 2.7
>>> from __future__ import unicode_literals
>>> type("chaine") <class 'str'>
chaîne Unicode
<type 'str'>
séquence d'octets
<type 'unicode'>
chaîne Unicode
>>> type(u"chaine") <class 'str'>
chaîne Unicode
<type 'unicode'>
chaîne Unicode
<type 'unicode'>
chaîne Unicode
>>> type(b"chaine") <class 'bytes'>
séquence d'octets
<type 'str'>
séquence d'octets
<type 'str'>
séquence d'octets

Ressources

Environnement virtuel

virtualenv

Pour créer un environnement virtuel, installer le paquet python3-virtualenv puis lancer la commande :

1
$ python3 -m virtualenv -p python3 venv

Activer ce nouvel environnement :

1
$ source venv/bin/activate

Pour le désactiver :

1
$ deactivate

Ressources

pip

Ressources

Utiliser l’autocomplétion avec l'IDE Atom

Le paquet autocomplete-python permet d'utiliser l’autocomplétion avec l'IDE Atom.

Utiliser des fichiers

Ouverture

Lorsqu'on ouvre un fichier en mode texte (mode par défaut), penser à spécifier l'encodage et le comportement en cas d'erreurs pour éviter les problèmes :

1
mon_fichier = open("fichier.txt", mode="r", encoding="utf_8", errors="strict")

En mode binaire, ne pas spécifier l'encodage :

1
mon_fichier_binaire = open("fichier.dat", mode="rb")

Signification de l'argument mode :

mode signification
"r" ouverture en lecture seule (défaut, synonyme de "rt")
"w" ouverture en écriture ; écrase le fichier existant
"x" ouverture en écriture ; échoue si le fichier existe déjà
"a" ouverture en écriture ; ajoute à la fin du fichier s'il existe
"b" mode binaire
"t" mode texte (défaut)
"+" ouverture pour mise à jour (lecture et écriture)

Les combinaisons pour l'argument mode les plus courants :

mode signification
"r" ouverture en mode texte, en lecture seule
"w" ouverture en mode texte, en écriture seule
"r+" ouverture en mode texte, en lecture et écriture, en ajoutant à la fin du fichier
"w+" ouverture en mode texte, en lecture et écriture, en écrasant le fichier existant
"rb" ouverture en mode binaire, en lecture seule
"wb" ouverture en mode binaire, en écriture seule

Fermeture

Attention

Penser à fermer le fichier après utilisation !

1
mon_fichier.close()

with open()

En utilisant le mot-clé with pour ouvrir un fichier, si une exception se produit, le fichier sera tout de même fermé à la fin du bloc :

1
2
with open("fichier.txt", mode="r", encoding="utf_8", errors="strict") as mon_fichier:
    # Opérations sur le fichier.

Lire l'ensemble du fichier :

1
2
with open("fichier.txt", mode="r", encoding="utf_8", errors="strict") as mon_fichier:
    contenu = mon_fichier.read()

Lire le fichier ligne par ligne :

1
2
3
with open("fichier.txt", mode="r", encoding="utf_8", errors="strict") as mon_fichier:
    for ligne in mon_fichier:
        # Opérations sur la ligne.

Écrire dans le fichier :

1
2
with open("fichier.txt", mode="w", encoding="utf_8") as mon_fichier:
    mon_fichier.write("une ligne")

Ressources

Erreurs et exceptions

Gestion des exceptions

Le bloc d'instructions qui suit directement une instruction try est exécuté par Python sous réserve. Si une erreur survient pendant l'exécution, de l'une de ces instructions, alors Python annule cette instruction fautive et exécute à sa place le code inclus dans le bloc qui suit l'instruction except. Si aucune erreur ne s'est produite dans les instructions qui suivent try, alors c'est le bloc qui suit l'instruction else qui est exécuté (si cette instruction est présente). Le bloc d'instructions qui suit l'instruction finally est toujours exécuté (si cette instruction est présente).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
try:
    # Bloc d'instructions susceptible de produire une erreur.
except:
    # Bloc d'instructions exécuté s'il survient une erreur lors de l'exécution
    # du bloc d'instructions suivant l'instruction « try ».
else:
    # Bloc d'instructions exécuté s'il ne survient aucune erreur
    # lors de l'exécution du bloc d'instructions suivant l'instruction « try ».
finally:
    # Bloc d'instructions exécuté quoi qu'il arrive lors de l'exécution
    # du bloc d'instructions suivant l'instruction « try ».

Il est possible de spécifier le type d'erreur à intercepter. Par exemple si une erreur de type ValueError intervient :

1
2
3
4
5
6
7
8
try:
    # Bloc d'instructions susceptible de produire une erreur.
except ValueError:
    # Bloc d'instructions exécuté s'il survient une erreur de type « ValueError »
    # lors de l'exécution du bloc d'instructions suivant l'instruction « try ».
except: # (optionnel)
    # Bloc d'instructions exécuté s'il survient une erreur de type autre que « ValueError »
    # lors de l'exécution du bloc d'instructions suivant l'instruction « try ».

Déclencher des exceptions

L'instruction raise permet au programmeur de déclencher une exception spécifique. Par exemple :

1
raise Exception("Une erreur s'est produite lors de l'exécution du programme !")
Toutes les exceptions définies par l'utilisateur devraient être dérivées de la classe Exception.

Ressources

Encodage et décodage JSON

On utilise le module json :

1
>>> import json

Encodage JSON

1
2
3
>>> dico = {"toto": "tata"}
>>> json.dumps(dico)
'{"toto": "tata"}'

Attention

Le module json produit toujours des objets str.

1
2
3
>>> dico = {"toto": "tata"}
>>> type(json.dumps(dico))
<class 'str'>

Si ensure_ascii est vrai (par défaut), il est garanti que les caractères non ASCII soient tous échappés sur la sortie. Si ensure_ascii est faux, ces caractères seront écrits comme tels.

1
2
3
4
5
>>> dico = {"toto": "éléphant"}
>>> print(json.dumps(dico))
{"toto": "\u00e9l\u00e9phant"}
>>> print(json.dumps(dico, ensure_ascii=False))
{"toto": "éléphant"}

Il existe des options supplémentaires bien pratiques comme indent et sort_keys :

1
2
3
4
5
6
>>> dico = {"b": "world!", "a": "Hello"}
>>> print(json.dumps(dico, indent=4, sort_keys=True))
{
    "a": "Hello",
    "b": "world!"
}

Décodage JSON

1
2
3
4
5
>>> texte = '{"toto": "éléphant"}' # texte unicode
>>> json.loads(texte)
{'toto': 'éléphant'}               # dictionnaire
>>> type(json.loads(texte))
<class 'dict'>

Encoder un fichier JSON

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#!/usr/bin/env python3
# -*- coding: utf_8 -*-

import json

dico = {"toto": "éléphant"}
texte = json.dumps(dico, ensure_ascii=False, indent=4)

with open("test.json", mode="w", encoding="utf_8") as mon_fichier:
    mon_fichier.write(texte)

Décoder depuis un fichier JSON

1
2
3
4
5
6
7
8
9
#!/usr/bin/env python3
# -*- coding: utf_8 -*-

import json

with open("test.json", mode="r", encoding="utf_8", errors="strict") as mon_fichier:
    contenu = mon_fichier.read()
    dico = json.loads(contenu)
    print(dico)

Ressources

Coroutines et tâches

Ressources

Les tests

Ressources

Serveur HTTP de développement

Un simple serveur de développement peut être lancé avec la commande suivante :

1
$ python3 -m http.server

Par défaut, ce serveur sert les fichiers disponibles dans le répertoire courant, à l'adresse http://0.0.0.0:8000/.

Ressources génériques


Dernière mise à jour: 23 juin 2021