principalement les structures de contrôle, et quelques-unes plus anecdotiques
nous laissons intentionnellement de coté le for pour le moment, ainsi que le try..except
l’instruction if¶
L’instruction conditionnelle en Python:
if <test1>:
<statement1>
elif <test2>:
<statement2>
...
else:
<statement4>repose sur une évaluation dite paresseuse, c’est-à-dire que l’instruction s’arrête au premier test qui est vrai (on n’évalue pas les tests suivants)
# par exemple
def appreciation(note):
if note >= 16:
return "félicitations"
elif note >= 14:
return "compliments"
elif note >= 12:
return "encouragements"
elif note >= 10:
return "passable"
else:
return "insuffisant"print(appreciation(15.5))compliments
print(appreciation(11.5))passable
if (l’expression)¶
il existe aussi une expression permettant de faire quelque chose comme if .. then .. else ..
la syntaxe générale est
<exp_1> if <test> else <exp_2>note = 8
# et comme c'est une expression, je peux par exemple
# la passer à une fonction
print("insuffisant" if note < 10 else "ouf !")insuffisant
boucle while¶
while <test>:
bloc d_instructions
alignés comme on l_a vu
else:
bloc # exécuté à la sortie de la boucle
aligné # seulement s’il n’y a pas de breakbreak, continue¶
deux instructions particulières:
continue: abandonner ce tour de boucle, passer au suivantbreak: sortir complètement de la boucle courante
on parle toujours de la boucle la plus imbriquée
# exemple avec continue
# on veut zapper les nombres pairs
L = [1, 5, 2, 7, 9]
while L:
n = L.pop()
if n % 2 == 0:
continue
# ... faire des trucs compliqués avec n
print(f"{n=}", end=" ")n=9 n=7 n=5 n=1 # exemple avec break
# dès qu'on trouve un nombre pair on s'arrête
L = [1, 5, 2, 7, 9]
while L:
n = L.pop()
if n % 2 == 0:
break
# ... faire des trucs compliqués avec n
print(f"{n=}", end=" ")n=9 n=7 match .. case¶
une toute nouvelle instruction match permet de définir des alternatives selon:
la taille d’une objet
la valeur dans un objet
et en fait pas mal d’autres choses...
# dans une version à-la switch
def http_error(status):
match status:
case 400:
return "Bad request"
case 404:
return "Not found"
case 418:
return "I'm a teapot"
case 401 | 403 :
return "Not allowed"
case _:
return "Something's wrong with the internet"
print(http_error(404))Not found
# mais on peut faire aussi plus complexe
# avec du pattern-matching, ici sur la valeur
# dans un tuple
def on_values(point: tuple[float, float]):
match point:
case (0, 0):
return "Origin"
case (0, y):
return f"null-x Y={y}"
case (x, 0):
return f"null-y X={x}"
case (x, y):
return f"regular X={x}, Y={y}"
case _:
raise ValueError("Not a point")
P = (0, 20)
print(on_values(P))null-x Y=20
# ou encore ici sur la taille d'un objet
def on_size(string):
match string.split():
case []:
return "no word"
case [w]:
return f"one word {w}"
case first, *rest:
return f"multi words starting with `{first}`"
print(on_size(""))
print(on_size("a b c"))no word
multi words starting with `a`
pour une introduction plus complète, voyez ceci https://
return¶
return sert tout simplement à indiquer la fin d’une fonction, et ce qu’elle doit renvoyer
lorsque le programme atteint cette instruction, la fonction courante s’arrête immédiatement
pass¶
l’instruction pass ne fait rien; elle est en général utilisée lorsque la syntaxe demande une instruction, mais qu’on ne l’a pas encore implémentée
def ma_fonction():
pass
class Foo:
passlibération de variables: del¶
del ainstruction qui libère la variable
a(en la supprimant de l’espace de nommage)et décrémente le compteur de références de l’objet vers lequel pointe
a
delfonctionne aussi surun slicing de séquence:
del L[i:j:k]un dictionnaire:
del D[clef]
exécuter du code¶
(avancé)
nous allons voir à présent deux fonctions, donc tehcniquement ce ne sont pas des instructions, mais bon ce n’est pas important
exec() et eval()¶
comment exécuter du code dans une chaîne de caractères ?
exec()est une fonction qui permet l’exécution dynamique de code pythonretourne toujours None
eval()est une fonction qui évalue une expression (mais pas une instruction)et retourne le résultat de cette évaluation
le code est bien sûr passé dans un
str
exec() pour une instruction¶
# instructions
i1 = """def fact(n):
return 1 if n <= 1 else n * fact(n-1)"""
i2 = """if fact(2) > 1:
print('OUI')"""# on peut les exécuter
# ceci ne fait rien que de définir une fonction
print(exec(i1))None
fact<function __main__.fact(n)># qu'on peut maintenant utiliser au travers de i2
# l'impression ici est faire dans le code de i2
# et puis None est le retour de exec
print(exec(i2))OUI
None
# par contre exec() ne renvoie rien d'utile
print(exec("fact(3)"))None
exec() vs eval()¶
# expressions
e1 = '(2+3)/2.0'
e2 = "{'alice' : 35, 'bob' : 8}"# on peut aussi les exécuter (une expression est une instruction)
# mais le retour est None ce qui perd de son intérêt
print(exec(e1))None
# c'est mieux de les évaluer
print(eval(e1))2.5
print(eval(e2)['alice'])35
eval() pour une expression¶
# par contre on ne peut pas évaluer une instruction
try:
res = eval(i1) # i1 est une instruction
except Exception as e:
print("Exception {} - {}".format(type(e), e))
import traceback
traceback.print_exc()Exception <class 'SyntaxError'> - invalid syntax (<string>, line 1)
Traceback (most recent call last):
File "/tmp/ipykernel_2561/1447414021.py", line 3, in <module>
res = eval(i1) # i1 est une instruction
^^^^^^^^
File "<string>", line 1
def fact(n):
^^^
SyntaxError: invalid syntax
use with care¶
je recommande de n’utiliser ces deux fonctions
que de manière spartiate
souvent pas réllement utile
gros trou de sécurité