Les exceptions sont utilisées pour signaler que quelque chose d'anormal se produit, une erreur généralement
Les messages d'erreur générés par les exceptions donnent des détails précieux sur les erreurs (type, emplacement, ...)
Si elles sont levées par Python vous pouvez capturer les exceptions (try
, except
) et modifier le comportement de votre script en fonction
Vous pouvez également lever des exceptions avec raise
chifoumi = ("pierre", "feuille", "ciseaux")
user_val = input("pierre, feuille, ciseaux ? ").lower()
if user_val not in chifoumi:
raise ValueError("pierre, feuille ou ciseaux et puis c'est tout")
val = [1, 2 ,3]
try:
print(val[1984])
except IndexError:
print("Erreur d'indice. Mais le roman est bien")
dico = {'michel': 'H', 'michèle': 'F'}
try:
print(dico[1984])
except IndexError:
print("Erreur d'indice. Mais le roman est bien")
Exception
réduit la précision de l'information sur l'erreur produitel = []
try:
print(dico[l[5]])
except Exception:
print("Soit la clé n'existe pas, soit l'indice n'existe pas")
l = [1,2,3,4,5]
try:
print(dico[l[5]])
except IndexError:
print("L'indice n'existe pas")
except KeyError:
print("La clé n'existe pas")
Le bloc else
sera exécuté si aucune exception n'est levée
Le bloc finally
sera exécuté dans tous les cas de figure
l = [1,2,3,4,5,0]
try:
print(dico[l[5]])
except IndexError:
print("L'indice n'existe pas")
except KeyError:
print("La clé n'existe pas")
else:
print("OK tout roule")
finally:
print("C'est fini, vous pouvez rentrer")
import logging
logging.basicConfig(filename='monscript.log',level=logging.INFO)
logging.debug('Celui-là ne sera pas dans les logs')
logging.info('Celui-là oui')
On peut formatter les log pour une sortie différente, souvent plus adaptée :
import logging
logging.basicConfig(filename='monscript.log', level=logging.INFO, format="%(levelname)s\t%(asctime)s\t%(message)s")
logging.debug('Celui-là ne sera pas dans les logs')
logging.info('Celui-là oui')
timeit
permet de mesurer le temps d'éxécution de portions de code ou de fonctions
La mesure du temps d'éxécution se fait en microseconde (usec), en milliseconde (msec) ou en secondes (sec)
Ce module s'utilise en ligne de commande, dans une console (i)python ou via des appels dans un script
Lors de l'appel en ligne de commande, le module détermine automatiquement le nombre de répétitions à réaliser
$ python3 -m timeit "[x**2 for x in range(100)]"
10000 loops, best of 3: 38.7 usec per loop
import timeit
def main():
time_char_in_str = timeit.timeit('str="le chat"; char="a"; char in str', number=10000)
print("Time char in str : {}".format(time_char_in_str))
time_find = timeit.timeit("""\
str = "le chat"
char="a"
char.find(str)
""", number=10000)
print("Time find : {}".format(time_find))
main()
Vous pouvez donner accès aux fonctions individuellement via le paramètre 'setup'
Le plus pratique est d'utiliser le paramètre global=globals()
pour lui passer l'espace de nom du script
import timeit
def f(n):
res = list()
for x in range(n):
res.append(x**2)
return res
def g(n):
return [x**2 for x in range(n)]
def main():
try:
print(timeit.timeit('f(10)', number=100000))
except NameError:
print("f n'est pas trouvée!") # on peut retirer le "try/catch" pour s'en convaincre
print(timeit.timeit('f(10)', number=100000, setup="from __main__ import f"))
print(timeit.timeit('g(10)', number=100000, globals=globals()))
main()
%timeit
et %%timeit
def f(n):
res = list()
for x in range(n):
res.append(x**2)
return res
%timeit -n 100000 "f(10)"
11.1 ns ± 2.77 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%%timeit
import random
l = [random.random() for xxx in range(100000)]
max(l)
8.58 ms ± 57.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%%timeit import random; l = [random.random() for xxx in range(100000)]
max(l)
1.36 ms ± 115 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
import argparse
parser = argparse.ArgumentParser(description="A useless script")
parser.add_argument("-v", "--verbose", help="verbose mode", action="store_true")
parser.add_argument("file", help="input file")
args = vars(parser.parse_args())
print(args['file'])
bash
> python3 args.py
usage: args.py [-h] [-v] file
args.py: error: the following arguments are required: file
On peut également utiliser --help
ou -h
pour afficher l'aide
bash
> python3 args.py -h
usage: args.py [-h] [-v] file
A useless script
positional arguments:
file input file
optional arguments:
-h, --help show this help message and exit
-v, --verbose verbose mode
Vous trouverez fréquemment le test suivant dans les scripts Python :
if __name__ == '__main__':
instruction1
instruction2
ou
def main():
instruction
if __name__ == '__main__':
main()
Cela évite que le code sous le test ne soit exécuté lors de l'import du script :
__name__
est une variable créée automatiquement qui vaut __main__
si le script a été appelé en ligne de commande, le nom du script s'il a été importé.
Accessoirement cela permet d'organiser son code et de le rendre plus lisible
Désormais je vous recommande vivement demande de l'inclure dans tous vos scripts