Skip to article frontmatterSkip to article content

tour d’horizon rapide du langage Python

commentaires

tout ce qui est après un # est un commentaire,
et sera ignoré par l’interpréteur Python

# ceci est un commentaire

10 * 10   # et ici aussi
100

importer une librairie

de nombreuses fonctionnalités ne sont pas dans le langage Python
elles sont disponibles dans des bibliothèques (en Python on dit un module) qu’on doit importer

La première manière de coder est de réutiliser l’existant !

# j'importe le module math
import math
# attention cette façon d'obtenir de l'aide est 
# spécifique à IPython / notebooks
# avec un interprète Python standard, on ferait 
# help(math)
math?

utiliser une librairie

une bibliothèque expose typiquement un certain nombre de symboles
par exemple dans math on va trouver

pour accéder à ces symboles on utilise la notation .

# ceci se lit comme:
# aller chercher l'attribut 'pi' dans l'objet module 'math'
math.pi
3.141592653589793
math.cos(math.pi)
-1.0

nombres

# entiers 
10
10
# flottants
3.14
3.14
# complexes
1j * (2+4j)
(-4+2j)
# booléens True et False
True
True
# les nombres ont des opérateurs (arithmétiques et de comparaison...)
# 3 est impair
10 % 3 == 1
True

précision des calculs flottants

bien sûr un flottant est représenté, en informatique, comme une suite de bits 0 ou 1
cela induit des calculs avec une précision imparfaite

# sur les architectures actuelles 
# un flottant est encodé sur 64 bits

0.2 + 0.1
0.30000000000000004
0.2 + 0.1 == 0.3
False
0.2 + 0.2 == 0.4
True
# cette fonction est pratique pour faire 
# un test de quasi-égalité sur les flottants
math.isclose(0.2+0.1, 0.3)
True

précision des calculs flottants

optionnel

la façon de passer d’un flottant à une séquence de bits
s’appelle un encodage dans le cas des flottants: IEE754
qui est efficace car supporté par le processeur

pour faire court - dans le cas le plus courant (binary64)
la précision des calculs est de l’ordre de 10-15

voir un convertisseur en ligne pour visuels

définir une variable

pour définir une variable, il suffit de l’affecter avec le signe =

# remarquez que ceci n'affiche rien
a = 10
# l'utilité c'est bien sûr 
# de garder un résultat pour
# s'en reservir ensuite
a + a
20

texte (chaînes de caractères)

# un texte est entre deux '

texte1 = 'bonjour le monde'
print(texte1)
bonjour le monde
# ou si on préfère entre "

texte2 = "bonjour le monde"
print(texte2)
bonjour le monde
# comme ça on peut insérer un "

print('Python est un langage "typé"')
Python est un langage "typé"
# ou un '

print("Python est un langage 'typé'")
Python est un langage 'typé'

print()

remarquez qu’on a utilisé la fonction print qui est prédéfinie
on peut l’appeler avec autant d’arguments qu’on veut
et de n’importe quel type

# simplement pour illustration des possibilités d'appel de fonction
# car on va voir plus loin une forme beaucoup plus pratique
# pour faire ce genre de choses
#
x = 12
print("la somme de", x, "et", 13, "vaut", x+13)
la somme de 12 et 13 vaut 25

formatage

pour construire des chaines lisibles,
le plus simple est la f-string

# une f-string se présente comme une chaine 
# mais préfixée par un f collé
# avant le guillement ouvrant
# qui peut être ' ou " 

f"une f-string"
'une f-string'
# l'intérêt est qu'on peut 
# alors insérer des variables
# directement dans la chaine
# en les mettant entre {}

print(f'pi = {math.pi}')
pi = 3.141592653589793
# en fait j'ai dit 'variable' mais on peut mettre n'importe quelle expression
# c'est à dire qu'à l'intérieur des {} on peut faire des calculs, ici sin(pi)
print(f"pi = {math.pi} et sin(pi) = {math.sin(math.pi)}")
pi = 3.141592653589793 et sin(pi) = 1.2246467991473532e-16

formatage - plus finement

il y a des tas de possibilités pour affiner la façon
dont les données sont mises en forme
pour cela ajouter un format dans les {} avec un :
par exemple pour afficher deux chiffres après la virgule :

print(f"bla {2*math.pi:.2f} bla")
bla 6.28 bla

fonctions

on définit une fonction avec le mot-clé def

# on définit une fonction en donnant son nom
# et les noms de ses paramètres
def P(x):
    return x**2 + 3*x + 2

vous remarquez que le code de la fonction est indenté
en effet python utilise l’indentation pour déterminer le bloc auquel appartient une instruction

# mintenant que la fonction est définie
# on peut maintenant l'appeler (l'exécuter)
P(10)
132
# une curiosité: True se comporte comme le nombre 1
P(True)
6

instructions

conditions, branchements, boucles ... Python a tout un ensemble d’instructions pour contruire vos programmes

x = 12
if x%2 == 0:
    print(f'{x} est pair')
else:
    print(f'{x} est impair')
12 est pair

python utilise l’indentation pour déterminer le bloc auquel appartient une instruction

x = 3
while x != 0:
    print(x)
    x = x-1
3
2
1
# à éviter d'exécuter ...
x = 3
while x != 0:
    print(x)
x = x-1

à quel bloc appartient x = x-1

itérations

parmi les instructions du langage, il y a la boucle for qui joue un rôle un peu à part (notion d’itérateurs et générateurs notamment)

# pour anticiper un peu
L = [1, 2, 3]
for item in L:
    print(item)
1
2
3
D = {'pierre': 20, 'jean': 32}
for key, value in D.items():
    print(key, '->', value)
pierre -> 20
jean -> 32

blocs

les blocs sont délimités par indentation, il n’y a pas de syntaxe de bloc à-la c avec des {...}
ce qui rend les codes un peu plus lisibles

mots clés

un certain nombre de mots sont réservés au langage;
ce sont les “mots-clé” du langage
on ne peut pas les utiliser comme noms de variable

# ceci provoque une erreur
if = 2

  File "<ipython-input>", line 3
    if = 2
       ^
SyntaxError: invalid syntax
liste    
Falseawaitelseimportpass
Nonebreakexceptinraise
Trueclassfinallyisreturn
andcontinueforlambdatry
asdeffromnonlocalwhile
assertdelglobalnotwith
asyncelififoryield

importer des symboles (variables, fonctions...)

on peut aussi faire comme ceci

from math import pi, sin

pi
3.141592653589793
# idem
sin(pi)
1.2246467991473532e-16

Préférez savoir d’où viennent les fonctions que vous utilisez.
C’est pourquoi on vous recommande fortement d’utiliser la forme math.sin plutôt que sin, qui garde la trace du module d’où provient le symbole sin.

On peut renommer une librairie
par exemple pour en raccourcir le nom

# la librairie numpy doit être installée
# dans votre environnement ...
import numpy as np
# grâce à la forme import .. as
# on a installé la librairie numpy
# mais dans notre code on l'utilise sous le nom np
np.sin(np.pi)
np.float64(1.2246467991473532e-16)

Remarquez qu’ici on devrait obtenir 0, mais les calculs sur les flottants sont faits de manière approchée.

containers

listes, ensembles, dictionnaires ... Python vous permet de définir des containeurs d’objets

# la liste permet de préserver l'ordre, avec d'éventuels duplicats
L = [10, 20, 10, 20, 10, 20]
L
[10, 20, 10, 20, 10, 20]
# l'ensemble au contraire élimine les duplicats
S = {10, 20, 10, 20, 10, 20}
S
{10, 20}
# le dictionnaire, c'est un peu comme un ensemble
# dans lequel chaque élément (qu'on appelle une clé)
# possède une valeur
D = {'dix': 10, 'vingt': 20}
D
{'dix': 10, 'vingt': 20}
# pour accéder, les indices commencent toujours à 0
print(L[0], L[5])
10 20
# dans les dictionnaires on accède par la clé
D['dix']
10
# on ne peut pas accéder au i-ème élément d'un ensemble
# mais on peut chercher si un élément existe
100 in S
False

pour les modifier

# liste ordonnée d'objets
# de type hétérogène
l = ['il', 12, 78.5, False, 'il']
l.append('bonjour')
print(l)
['il', 12, 78.5, False, 'il', 'bonjour']
# ensemble d'objets de type hétérogène
s = {'il', 12, 78.5, False, 'il'}
s.add('bonjour')
print(s)
{False, 'il', 12, 78.5, 'bonjour'}
# dictionnaire i.e. ensemble de couples (clé, valeur)
d = {'zero':0, 'un':1,'trois':3}
d['deux'] = 2 
print(d)
{'zero': 0, 'un': 1, 'trois': 3, 'deux': 2}

len()

il existe une fonction prédéfinie très pratique: len()
qui retourne la longeur d’un objet (le nombre d’éléments qu’il contient)

# sur une chaine len()
# retourne le nombre de caractères
#
# remarquez que les guillemets ne comptent pas
len("abc")
3
# on compte les caractères 
# et pas les octets

len("été")
3
# sur un objet d'un type structuré
# retourne le nombre d'éléments
d = {'zero': 0, 'un': 1, 'trois': 3}
len(d)
3

textes plus longs

si vous avez besoin d’écrire des textes de plusieurs lignes
utilisez """ au lieu de " -- (ou ''')

bafouille = \
"""To be, or not to be: that is the question:
Whether 'tis nobler in the mind to suffer
The slings and arrows of outrageous fortune,"""
print(bafouille)
To be, or not to be: that is the question:
Whether 'tis nobler in the mind to suffer
The slings and arrows of outrageous fortune,
# idem avec '''
# le changement de ligne compte 
# pour un caractère (newline) 
court = '''a
b'''
print(court)
a
b
# les caractères sont 'a', '\n', et 'b'
len(court)
3

types

pas besoin de préciser le type d’un objet, Python le déduit tout seul
tout a un type: les variables, les fonctions les modules ...

a = 10
type(a)
int
b = -17.5
type(b)
float
# le résultat d'une expression
# est un objet et du coup il a un type
type(10 < 3)
bool
# une fonction usuelle
def incr (x):
    return x+1

type(incr)
function
# une fonction builtin
type(len)
builtin_function_or_method
# un module
import math
type(math)
module

écrire dans un fichier

en 3 étapes: on ouvre un fichier, on écrit dedans et on ferme le fichier

# on écrit des chaînes de caractères
file = 'hamlet.txt'
f = open(file, 'w') # w pour le mode écriture
f.write(bafouille)
f.write('Or to take Arms ...')
f.close()
# ne pas oublier de fermer le fichier !

cette première façon de faire c’est la version ‘pédestre’ mais c’est très old-school, et pas du tout recommandé; on la montre juste pour bien décortiquer ce qui est fait

la bonne façon de faire, c’est celle-ci:

# en beaucoup beaucoup plus élégant ....
file = 'hamlet.txt'

with open(file, 'w') as f:
    f.write(bafouille)
    f.write('Or to take Arms ...')
# vous ne pouvez pas oublier
# de fermer le fichier

on peut aussi utiliser print(des, trucs, file=f) plutôt que write

lire le contenu d’un fichier

# tout le contenu
file = 'hamlet.txt'
with open(file, 'r') as f:
    print(f.read())
To be, or not to be: that is the question:
Whether 'tis nobler in the mind to suffer
The slings and arrows of outrageous fortune,Or to take Arms ...
# ligne par ligne
file = 'hamlet.txt'
with open(file, 'r') as f:
    for line in f:
        print(line, end='') # la fin de ligne est ''
To be, or not to be: that is the question:
Whether 'tis nobler in the mind to suffer
The slings and arrows of outrageous fortune,Or to take Arms ...

définir de nouveaux types - avancé

on peut introduire dans Python de nouveaux types de données

vous avez besoin d’objets de type rationnel ?
construits à partir d’un numerator et d’un denominator ?
avec des fonctions de réduction et d’affichage ?

r = Rational(2, 4)
r.reduce()
print(r) # affiche 1/2
class Rational:
    
    # le constructeur
    def __init__ (self, n, d):
        # self est par convention l'objet qu'on construit
        self.num = n # on range un attribut dans l'objet construit
        self.denom = d # on range un autre attribut dans self
        
    # une méthode = une fonction qui travaille sur un objet (ici self)
    def reduce (self):
        # à vous de la faire ...
        pass
    
    # la méthode qui sera appelée
    # quand votre objet sera affiché ou mis dans une chaîne de caractère
    def __str__ (self):
        return f'{self.num}/{self.denom}'

# on construit un objet de type Rational
# de numérateur 2 et dénominateur 4
r = Rational(2, 4)

# on le réduit ... (si vous implémentez la fonction)
r.reduce()

print(r) # on l'affiche sous la forme 1/2 si reduce est implémentée, sinon 2/4

# on le représente
r # pour changer cette représentation assez technique ... implémentez la fonction __repr__
2/4
<__main__.Rational at 0x7f78f010b560>

type prédéfinis

int, bool, float, str, list, dict, set ... tous ces types sont eux même définis par des classes
et donc tous ces types ont aussi des méthodes ...

# je construis une liste vide
l = list()
len(l)
0
# j'ajoute des éléments en fin de liste
l.append(12)
l.append(13)
print(l)
[12, 13]
# méthodes sur les chaines
chaine = "bonjour"

chaine.capitalize()
'Bonjour'

deux méthodes très utiles sur les chaines : split et join

longue_chaine = "une liste de mots à découper"
# sert à découper une chaine 
# en morceaux

mots = longue_chaine.split()
mots
['une', 'liste', 'de', 'mots', 'à', 'découper']
# et avec join on peut réassembler
# avec le caractère spécifié

"+".join(mots)
'une+liste+de+mots+à+découper'

python ... et la question du style

tout code Python est censé obéir à un style très précis décrit ici https://www.python.org/dev/peps/pep-0008/

Pourquoi ?

parce que, comme le dit Guido Van Rossum un code est beaucoup plus souvent lu qu’il n’est écrit
aussi est-il important s’assurer la lisibilité et la cohérence de vos codes

objets et types

optionnel

Python est orienté objet; ça signifie que:

# on peut toujours appeler type() 
x, y = 1, 3.14
type(x)
type(y)
float
# une variable peut changer de type
x = [1, 2, 3]
type(x)
list
# vraiment tout a un type
import math
type(math)
module
# vraiment tout a un type
def foo(x):
    pass
type(foo)
function
# vraiment tout a un type
type(None)
NoneType
# vous avez compris l'idée générale
type(type(x))
type