La syntaxe Python
∗
Guillaume Wisniewski
guillaume.wisniewski@limsi.fr
septembre 2010
R´esum´e
Ce document a pour objectif de pr´esenter rapidement la syntaxe de Python ainsi que certaines constructions et biblioth`eques que nous utiliserons dans ce cours. Une introduction plus d´etaill´ee au langage est disponible `a l’url http://docs.python.org/tutorial/.
Table des mati`
eres
1
Ex´
ecuter un programme python
Il y a deux mani`ere d’ex´ecuter un programme python :
– soit en sauvegardant le programme dans un fichier (ayant g´en´eralement l’ex-tension .py) et en ex´ecutant la commande : python mon_fichier.py. – soit en utilisant directement l’interpr´eteur : en lan¸cant le programme python
il est possible d’entrer directement des commandes qui seront ex´ecut´ees au fur et `a mesure de leur saise.
Dans les exemples de ce document, nous utiliserons cette derni`ere m´ethode : les lignes commen¸cant par In [1]: correspondent aux commandes qui sont saisies et les autres aux « r´eponses » de l’interpr´eteur.
2
Types standards
2.1
Type de base
Python est un langage typ´e dynamiquement : le type d’une variable est d´etermin´e par l’interpr´eteur au moment de l’ex´ecution et n’a pas besoin d’ˆetre d´eclar´e :
∗Ces notes sont bas´ees sur une pr´esentation de Christopher Burns et Ga¨el Varoquaux `a Scipy’09 http://conference.scipy.org/static/wiki/python4science -2x1.pdf
In [17]: a = 1 # a est de type integer
In [18]: b = 2.0 # b est de type float
In [19]: a = "le chat" # a est maitenant de type string
In [1]: c = 3 + 2j # nombre complexes
In [2]: print c Out[2]: (3+2j)
In [3]: d = 1 == 2 # bool´eens
In [4]: d # dans l’interpr´eteur, le print n’est pas obligatoire
Out[4]: False In [1]: e, f = 3, 2.1
On remarquera que :
– le marqueur de fin de ligne est le retour chariot et non le point virgule comme dans la plupart des autres langage ;
– le caract`ere # permet d’indiquer un commentaire ;
– il est possible d’effectuer plusieurs assignations simultan´ement.
2.2
Collections
Python fournit de mani`ere standard diff´erents types de collections. Chacune de ces collections est un objet et il est donc possible d’utiliser les m´ethodes d’exploration dynamique pour connaˆıtre la liste des m´ethodes disponibles (cf. paragraphe ??).
2.2.1 Listes
a = [1, 2, 3, 4, "maman", 5.1]
Les listes peuvent stocker, de mani`ere ordonn´ee, des ´el´ements de diff´erents types. Il est possible :
– d’acc´eder directement `a un ´el´ement In [4]: r = [1, 2, 3, 7] In [5]: r[2] Out[5]: 3 In [6]: r[-1] Out[6]: 7 In [11]: r[-3] Out[11]: 2
En utilisant des indices n´egatifs, il est possible d’acc´eder aux ´el´ements en partant de la fin (l’indice −1 correspond au dernier ´el´ement, −2 `a l’avant-dernier, ...)
– d’extraire des sous-listes :
# tous les ´el´ements renvoy´es sont des listes
In [4]: r Out[4]: [1, 2, 3, 7] In [7]: r[3:] Out[7]: [7] In [8]: r[2:] Out[8]: [3, 7] In [9]: r[:2] Out[9]: [1, 2] In [10]: r[::2] Out[10]: [1, 3]
La syntaxe g´en´erale est : [indice d´ebut:indice fin:pas]. Ces param`etres sont facultatifs : par d´efaut, indice d´ebut correspond au premier indice de la liste (0), indice fin au dernier indice et pas `a 1. En utilisant des pas n´egatifs, il est possible de parcourir la liste `a l’envers. Par exemple a[::-1] permet d’inverser la liste (on parcours la liste du d´ebut `a la fin avec un pas de −1).
– d’ajouter des ´el´ements `a une liste In [12]: a = [1, 2, 3] In [13]: a.append(4) In [14]: print a [1, 2, 3, 4] In [15]: b = [5, 6] In [16]: a + b Out[16]: [1, 2, 3, 4, 5, 6] – de trier une liste
In [2]: r = [2, 7, 1, 3]
# la liste est en tri´ee « en place » # => renvoie None
In [3]: r.sort()
# cr´ee une nouvelle liste tri´ee
In [5]: a = sorted(r) In [4]: print r Out[4]: [1, 2, 3, 7]
In [7]: a = ["le", "petit", "chat"] In [8]: "-".join(a)
Out[8]: ’le-petit-chat’ 2.2.2 Des dictionnaires
Les dictionnaires permettent d’associer deux objets quelconques : le premier objet d´efinit une cl´e ; le suivant la valeur qui lui est associ´e.
In [29]: d = {’a’: 1, ’b’:1.2, ’c’:1j} In [30]: d[’b’] Out[30]: 1.2 In [31]: d[’d’] = ’d’ In [32]: d Out[32]: {’a’: 1, ’b’: 1.2, ’c’: 1j, ’d’: ’d’} In [33]: d.keys() Out[33]: [’a’, ’c’, ’b’, ’d’] In [34]: d.values() Out[34]: [1, 1j, 1.2, ’d’]
2.2.3 Les chaˆınes de caract`eres a = ’Mine’
a = "Chris’s"
# cha^ınes sur plusieurs lignes
a = ’’’Mine
and not his’’’ a = """Mine
and Chris’s"""
– les chaˆınes de caract`eres sont des listes : In [35]: s = ’Python is cool’
In [36]: s[-4:] Out[36]: ’cool’
– python fournit plusieurs m´ethodes int´eressante : In [1]: a = "Python is cool"
In [2]: a.replace("cool", "powerful") Out[2]: ’Python is powerful’
In [3]: a.lower() Out[3]: ’python is cool’
Nous verrons au paragraphe ?? comment d´ecouvrir facilement la liste compl`ete des m´ethodes disponibles.
– substitution de chaˆıne de caract`eres
In [38]: ’An integer: %i; a float: %f; another string: %s’ % (1, 0.1, ’string’) Out[38]: ’An integer: 1; a float: 0.100000; another string: string’
– construction d’une liste : In [9]: "1;2;3;4".split(";") Out[9]: [’1’, ’2’, ’3’, ’4’]
In [11]: "1 2 3 4".split() Out[11]: [’1’, ’2’, ’3’, ’4’]
split(sep) retourne la liste des mots contenus dans une chaˆıne de caract`eres en supposant que ceux-ci sont s´epar´es par sep. Si sep n’est pas fournit split consid`ere que les mots sont s´epar´es par un ou plusieurs espaces.
3
Structure de contrˆ
ole
3.1
Conditions
In [23]: if a == 1: ....: print 1 ....: elif a == 2: ....: print 2 ....: else: ....: print "beaucoup" ....: ....: beaucoupOn remarquera que, en Python, les blocs sont d´elimit´es par l’indentation et seulement par l’indentation : il n’y a pas de begin/end ou d’accolades. Les conditions peuvent porter :
– soit sur des expressions bool´eennes
– soit sur des objets : un objet est vrai si sa valeur n’est pas nulle ou si sa longueur est strictement plus grande que 0 (pour les s´equences) :
In [1]: a = [] In [2]: if a: ...: print 1 ...: else: ...: print 2 ...: ...: 2
– il est ´egalement possible de tester si un objet appartient `a une collection en utilisant le mot-cl´e in
In [19]: a = [1, 2, 3, 5] In [20]: 2 in a
Out[20]: True
# pour les dictionnaires in teste l’existence d’une cl´e
In [21]: b = {"name": "Guillaume", 2:3} In [22]: 2 in b
Out[22]: True
In [23]: "Guillaume" in b Out[23]: False
# pour les string
In [1]: a = "le chat et le chien" In [2]: "chien" in a
Out[2]: True
In [3]: "poisson" in a Out[3]: False
3.2
Boucles
Pour it´erer sur un index : In [24]: for i in range(4): ....: print i ....: ....: 0 1 2 3
Cette boucle est ´equivalente au code C suivant : int i = 0;
// ...
for (i = 0; i < 4; i++) { printf("%d\n", i); }
La fonction range permet de construire une liste d’entiers cons´ecutifs : range(4) = [0, 1, 2, 3]. Il est possible d’it´erer sur n’importe quelle s´equence :
In [25]: for word in [’cool’, ’powerful’, ’readable’]:
....: print(’Python is %s’ % word)
....:
....: Python is cool
Python is powerful Python is readable et mˆeme : In [26]: vowels = ’aeiouy’ In [27]: for i in ’powerful’: ....: if i in vowels: ....: print i, ....: ....: o e u
La virgule `a la fin du print permet d’´eviter le retour chariot. Python dispose ´egalement d’une boucle while
In [28]: z = 1 + 1j In [29]: while abs(z) < 100: ....: if z.imag == 0: ....: break ....: z = z ** 2 + 1 ....: ....:
3.3
Utilisation avanc´
ee des boucles
La boucle for permet de parcourir les ´el´ements d’un dictionnaire : In [7]: d = {’a’: 1, ’b’:1.2, ’c’:1j}
In [8]: for key, val in d.iteritems():
...: print(’Key: %s has value: %s’ % (key, val))
...:
...:
Key: a has value: 1
Key: c has value: 1j Key: b has value: 1.2
In [10]: for key in d: ....: print key ....: ....: a c b
Il est possible de construire directement des listes `a l’aide de list comprehension : In [4]: [i ** 2 for i in range(4)]
In [5]: vowels = ’aeiouy’
In [6]: [i for i in "powerfull" if i in vowels] Out[6]: [’o’, ’e’, ’u’]
Pour parcourir une liste en conservant les indices des ´el´ements, on peut utiliser le mot-cl´e enumerate :
In [12]: word = "le chat"
In [13]: for index, lettre in enumerate(word):
....: print index, lettre
....: ....: 0 l 1 e 2 3 c 4 h 5 a 6 t
4
D´
efinir des fonctions
Une fonction est d´efinie par le mot-cl´e def : In [1]: def area(radius):
...: return 3.14 * radius * radius
...:
In [2]: area(1.5)
Out[2]: 7.0649999999999995
Comme pour les structures de contrˆoles, le corps de la fonction est d´elimit´e par l’indentation. Une fonction peut, de mani`ere optionnelle, renvoyer une valeur grˆace au mot-cl´e return.
Au moment de l’appel, l’interpr´eteur s’assure que le nombres de param`etres de la fonction est correct :
In [3]: def double_it(x): ...: return x * 2 ...: In [4]: double_it(3) Out[4]: 6 In [5]: double_it()
---TypeError Traceback (most recent call last)
TypeError: double_it() takes exactly 1 argument (0 given)
Il est ´egalement possible de d´efinir des param`etres ayant des valeurs par d´efaut : In [6]: def double_it(x=2): ...: return x * 2 ...: In [7]: double_it(3) Out[7]: 6 In [8]: double_it() Out[8]: 4
On peut sp´ecifier les param`etres en utilisant leur nom : In [9]: def slicer(seq, start=None, stop=None, step=None):
...: """Implement basic python slicing."""
...: return seq[start:stop:step]
...:
In [10]: seuss = ’one fish, two fish, red fish, blue fish’.split() In [11]: seuss
Out[11]: [’one’, ’fish,’, ’two’, ’fish,’, ’red’, ’fish,’, ’blue’, ’fish’] In [12]: slicer(seuss)
Out[12]: [’one’, ’fish,’, ’two’, ’fish,’, ’red’, ’fish,’, ’blue’, ’fish’] In [13]: slicer(seuss, step=2)
Out[13]: [’one’, ’two’, ’red’, ’blue’] In [14]: slicer(seuss, 1, step=2)
Out[14]: [’fish,’, ’fish,’, ’fish,’, ’fish’] In [15]: slicer(seuss, start=1, stop=4, step=2) Out[15]: [’fish,’, ’fish,’]
Il est possible qu’une fonction retourne plusieurs valeurs : from __future__ import division
def mean_var(lst): """
Calcule la moyenne et la variance d’une liste """
mean = sum(lst) / len(lst)
var = sum([(x - mean) ** 2 for x in lst]) / len(lst) return mean, var
Cette exemple montre plusieurs ´el´ements int´eressant de python : – la possibilit´e de retourner plusieurs valeurs dans une fonction ; – l’utilisation des fonctions sum et len ;
– l’utilisation des docstring (la chaˆıne de caract`eres sous le nom de la fonction) pour documenter la fonction ;
– l’utilisation du from __future__ import division pour que / corresponde `
a la division naturelle et non plus `a la division enti`ere.
Il est possible d’acc´eder `a la docstring d’une fonction directement depuis l’in-terpr´eteur python grˆace `a la commande help
In [18]: help(mean_var)
Help on function mean_var in module __main__: mean_var(lst)
Calcule la moyenne et la variance d’une liste
5
Les objets
Voici un exemple d’objet en python class Basket:
# attention: le premier argument doit toujours ^etre une r´ef´erence # `a l’objet, appel´ee, par convention, self
def __init__(self, contents=None): if contents:
self.contents = contents else:
self.contents = [] def add(self, element):
self.contents.append(element) def n_elements(self):
"""
Nombre d’´el´ements dans le panier """
return len(self.contents) def __str__(self):
"""
m´ethode qui est appel´ee par print (´equivalent de toString en Java """
result = ""
for element in self.contents: result = result + " " + element return "Contains: %s" % result def str_python(self):
Une mani`ere plus dans l’esprit de python de coder __str__ """
return "contains: %s" % " ".join(self.contents) b = Basket()
b.add("carottes") b.add("melon")
print b # appel `a __str__
1. toutes les m´ethodes de l’objet prennent obligatoirement, en premier argu-ment une r´ef´erence `a l’objet (correspondant au this en Java ou en C++). Par convention, cet argument s’appelle toujours self.
2. la m´ethode correspondant au constructeur s’appelle __init__ ; pour cr´eer un objet il suffit d’appeller le nom de l’objet en passant les param`etres (b = Basket())
3. il n’y a pas de mode d’acc`es en python (private, public en java) ; tous les attributs sont publics1.
4. si b est une r´ef´erence sur un objet, on peut acc´eder `a ses attributs par b.nom_attribut et appeler ses m´ethodes par b.methode() (en fournis-sant, si n´ecessaire, les param`etres)
6
Biblioth`
eque
6.1
Syntaxe
Il est possible d’utiliser des biblioth`eques, apr`es les avoirs import´ees par la com-mande from biblio import fonction1, fonction2. Certaines biblioth`eques d´efinissent de nouveaux objets qui peuvent ˆetre import´es de la mˆeme mani`ere. Python fournit de nombreuses biblioth`eques de mani`ere standard. On notera notamment :
– os qui contient des fonctions permettant de manipuler le syst`eme de fichier ; – re pour utiliser des expressions r´eguli`eres ;
– codec pour lire des fichiers contenant des accents ;
– sys qui permet d’acc´eder au syst`eme et notamment aux entr´ees et sorties standards ;
– pickle qui permet de sauvegarder (et de recharger) un objet dans un fichier. Il est possible de d´efinir ses propres biblioth`eques. Si l’on suppose que l’on dispose d’un fichier corpus.py d´efinissant une fonction build_from_directory et d’une classe Corpus, il est possible d’utiliser ceux-ci dans n’importe quel autre fichier python apr`es avoir fait :
from corpus import Corpus, build_from_directory
Il faut toutefois que les deux fichiers soient dans le mˆeme r´epertoire.
1L’encapsulation (qui n’est qu’une question de style !) est assur´ee par un m´ecanisme beau-coup plus puissant, les propri´et´es.
6.2
Aide dynamique
Il est possible de connaˆıtre le contenu d’un module de mani`ere dynamique `a l’aide des commandes dir et help :
# les sorties des exemples suivants sont tronqu´ees
In [25]: import os In [26]: dir(os) Out[26]: [’fdopen’, ’fork’, ’forkpty’, ’fpathconf’, ’fstat’, ’fstatvfs’, ’fsync’, ’ftruncate’, ’getcwd’, ’getcwdu’, ’getegid’, ’getenv’, ’geteuid’, ’getgid’, ’getgroups’] In [27]: help(os) Help on module os: NAME
os - OS routines for Mac, NT, or Posix depending on what system we are on.
FILE
/people/wisniews/local/lib/python2.6/os.py MODULE DOCS
http://docs.python.org/library/os DESCRIPTION
This exports:
- os.path is one of the modules posixpath, or ntpath
- os.name is ’posix’, ’nt’, ’os2’, ’ce’ or ’riscos’
La commande dir permet d’acc´eder aux noms des fonctions et des objets conte-nus dans un module et des m´ethodes d’un objet ; la commande dir permet d’obtenir l’aide correspondant `a une variable, `a une fonction, `a un objet ou `a un module. Cette aide est d´efinie par les docstring.
In [28]: a = {} In [29]: dir(a) Out[29]: [’clear’,
’fromkeys’, ’get’, ’has_key’, ’items’, ’iteritems’, ’iterkeys’, ’itervalues’, ’keys’, ’pop’, ’popitem’, ’setdefault’, ’update’, ’values’] #sortie tronqu´ee In [30]: help(a.iterkeys)
Help on built-in function iterkeys: iterkeys(...)
D.iterkeys() -> an iterator over the keys of D (END)
7
Utilisation de fichiers
L’ouverture et la fermeture d’un fichier se font par l’interm´ediaire des com-mandes open et close :
In [67]: fp = open("holy_grail.txt", mode="r") In [68]: fp
Out[68]: <open file ’holy_grail.txt’, mode ’r’ at 0xea1ec0>
In [73]: fp.close()
Un fichier peut ˆetre ouvert dans les modes suivant : – lecture seul (mode="r")
– ´ecriture seule (mode="w", si le fichier existe il est alors ´ecras´e) – ajout (mode="a")
Il est possible de lire un fichier ligne par ligne ou de lire toutes les lignes dans une liste en une seule op´eration :
In [50]: fp = open("holy_grail.txt") In [69]: first_line = fp.readline() In [70]: first_line
Out[70]: "GUARD: ’Allo, daffy English kaniggets and Monsieur Arthur-King, who is\n" In [76]: all_lines = fp.readlines()
Out[77]:
["GUARD: ’Allo, daffy English kaniggets and Monsieur Arthur-King, who is\n", ’ afraid of a duck, you know! So, we French fellows out-wit you a\n’, ’ second time!\n’,
’ \n’,
...
’ \n’]
In [78]: all_lines[0]
Out[78]: "GUARD: ’Allo, daffy English kaniggets and Monsieur Arthur-King, who is\n" En utilisant une boucle for, il est possible d’it´erer directement sur les lignes d’un fichier :
In [81]: fp = open("holy_grail.txt") In [82]: for line in fp:
....: print line
....:
GUARD: Allo, daffy English kaniggets and Monsieur Arthur-King, who is afraid of a duck, you know ! So, we French fellows out-wit you a second time !
La m´ethode write permet d’´ecrire dans un fichier : In [83]: fp = open(’newfile.txt’, ’w’)
In [84]: fp.write("I am not a tiny-brained wiper of other people’s bottoms!") In [85]: fp.close()
In [86]: fp = open(’newfile.txt’) In [87]: fp.read()
Out[87]: "I am not a tiny-brained wiper of other people’s bottoms!"
Il est possible de sauvegarder directement des objets Python dans un fichier grˆace au module pickle.
import pickle
# exemple de sauvegarde d’objet
data = {’a’: [1, 2.0, 3, 4+6j],
’b’: (’string’, u’Unicode string’), ’c’: None}
output = open(’data.pkl’, ’wb’) pickle.dump(data, output) output.close()
# pour recharger l’objet
pkl_file = open(’data.pkl’, ’rb’) data = pickle.load(pkl_file) print data
pkl_file.close()
8
Correcteur orthographique en python
2Nous allons maintenant illustrer les diff´erents aspects de Python en ´etudiant un programme de correction orthographique complet. Le principe de ce correcteur est relativement simple : si l’on suppose que l’on dispose d’une liste de tous les mots avec leur fr´equence d’apparition (un dictionnaire, il suffit, pour v´erifier l’orthographe d’un mot de g´en´erer une liste de corrections possibles et choisir, parmi celles-ci, la plus fr´equente.
Voici un programme python mettant en œuvre ce principe : import re, collections
def words(text):
return re.findall(’[a-z]+’, text.lower()) def train(features):
model = collections.defaultdict(lambda: 1) for f in features:
model[f] += 1
return model
NWORDS = train(words(file(’big.txt’).read())) alphabet = ’abcdefghijklmnopqrstuvwxyz’ def edits1(word):
s = [(word[:i], word[i:]) for i in range(len(word) + 1)] deletes = [a + b[1:] for a, b in s if b]
transposes = [a + b[1] + b[0] + b[2:] for a, b in s if len(b) > 1] replaces = [a + c + b[1:] for a, b in s for c in alphabet if b] inserts = [a + c + b for a, b in s for c in alphabet] return set(deletes + transposes+ replaces + inserts) def known(words):
return set(w for w in words if w in NWORDS) def correct(word):
candidates = known([word]) or known(edits1(word)) or [word] return max(candidates, key=NWORDS.get)
– les fonctions words et train construisent le dictionnaire en i) segmentant un texte en mot et en ii) comptant le nombre d’occurrences de chaque mot ; 2d’apr`es http ://norvig.com/spell-correct.html
– la fonction edits1 permet de g´en´erer une liste de corrections possibles en consid´erant :
– tous les mots obtenus en supprimant une des lettres du mot `a corriger ; – tous les mots obtenus en ´echangeant deux lettres adjacentes ;
– tous les mots obtenus en rempla¸cant une des lettres du mot `a corriger ; – tous les mots obtenus en ajoutant une lettre au mot `a corriger (`a toutes les
positions possibles) ;
Cette ensemble de correction n’est pas complet, mais il couvre la plupart des erreurs commises.
– la fonction known filtre les corrections possibles (g´en´er´ees par edits1 en ne gardant que celles qui sont dans le dictionnaire.
– la fonction correct parcourt la liste de toutes les corrections possibles et trouve la correction la plus fr´equente, la premi`ere ligne de la fonction permet de s´electionner le premier ensemble qui n’est pas vide.