Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

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))
The history saving thread hit an unexpected error (OperationalError('attempt to write a readonly database')).History will not be written to the database.
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 break

break, continue

deux instructions particulières:

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:

# 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://peps.python.org/pep-0636/

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:
    pass

libération de variables: del

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()

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_648/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