Licence CC BY-NC-ND, Thierry Parmentelat & Arnaud Legout
from IPython.display import HTML
HTML(filename="_static/style.html")
fonctions: rappels#
objectifs de cette section#
dans cette partir consacrée aux fonctions, nous allons approfondir le sujet, et notamment creuser
le passage de paramètres
les fonctions comme citoyen de niveau 1
la visibilité des variables
mais pour commencer, voici quelques rappels et généralités sur ce thème
pour réutiliser du code en python#
DRY = don’t repeat yourself : cut’n paste is evil
fonctions |
pas d’état après exécution |
modules |
garde l’état, une seule instance par programme |
classes |
instances multiples, chacune garde l’état, héritage |
les docstrings#
où documenter ?#
si, dans un objet de type fonction, classe ou module, la première instruction est une chaîne de caractères
alors c’est le docstring de cet objet, qui constitue sa documentation
l’idée étant naturellement de pouvoir maintenir en même temps le code et la doc, plutôt que d’avoir la doc dans un système séparé qui du coup n’est jamais à jour
def hyperbolic(x, y):
"""
computes xˆ2 - y^2
"""
return x**2 - y**2
c’est ce qui est utilisé pour afficher la doc avec help(objet)
help(hyperbolic)
Help on function hyperbolic in module __main__:
hyperbolic(x, y)
computes xˆ2 - y^2
l’attribut spécial doc
pour information, cette chaine est rangée dans l’espace de nom de l’objet dans un attribut spécial hyperbolic.__doc__
comment documenter ?#
c’est une bonne habitude de toujours documenter !
le plus souvent multiligne - avec
"""comme danshyperbolicpas utile de répéter le nom de l’objet, qui est extrait automatiquement de la signature (DRY)
la première ligne décrit brièvement ce que fait l’objet
la deuxième ligne est vide
les lignes suivantes décrivent l’objet avec plus de détails - notamment les paramètres, etc…
format et exemple#
historiquement le contenu du docstring était basé sur ReST, mais jugé peu lisible
du coup pas forcément hyper-bien standardisé - plusieurs conventions existent dans le code disponible
recommande personnellement:
styles
googleet/ounumpyvoir doc ici
un exemple réaliste
voici un exemple sur une librairie réelle, et qui suit un workflow assez commun:
le source est posté sur
github.comà chaque commit, un webhook informe
readthedocs.ioet la doc est recalculéele moteur pour recalculer cette doc est l’outil
Sphinxvoici la doc telle que publiée sur
readthedocs.io
https://asynciojobs.readthedocs.io/en/main/API.html#asynciojobs.purescheduler.PureScheduleret le code source correspondant sur github parmentelat/asynciojobs
PEP8#
d’après la PEP8, on doit
utiliser une (ou plusieurs) ligne(s) vide(s) pour séparer les fonctions, classes et les grands blocs d’instructions
rappel: les noms de fonctions sont en minuscules
rappel: espace autour des opérateurs et après les virgules
a = f(1, 2) + g(3, 4)rappel: des espaces autour de l’
=, et pas après la fonction
f(1, 2)et non pascar un espace en tropf (1, 2)
a = f(1, 2)et non pascar manque des espacesa=f(1, 2)
passage d’arguments et références partagées#
le passage de paramètres se fait par référence
ce qui crée donc des références partagées
et donc une fonction peut modifier les objets qu’on lui passe
# nous allons illustrer ce mécanisme de
# références partagées grâce à pythontutor.com
%load_ext ipythontutor
%%ipythontutor curInstr=2 width=1000 height=400
# les arguments d'une fonction sont toujours passés par référence
liste = [1, 2, 3]
def mess_with(reference):
reference[1] = 100
mess_with(liste)
print(liste)
%%ipythontutor width=800 height=450 heapPrimitives=true
def mess_with2(a, b):
a = 3 # ceci n'aura pas de conséquence sur A
b[0] = 'boom' # ceci va changer B
A = 1 # immutable ne peut pas être modifiée
B = [10, 20] # mutable, l'objet liste est modifié par
# changer() par une modification in-place
mess_with2(A, B)
print(A)
print(B)
comment définir une fonction ?#
syntaxe#
defcrée un objet fonction, et l’assigne dans la variablenameassimilable à une simple affectation
name = ..tout est objet en Python, la fonction aussi !
bien entendu, le code n’est évalué que quand la fonction est appelée
une fonction peut modifier ses paramètres !
les arguments sont passés par référence
donc crée des références partagées
attention aux types mutables, ils peuvent être modifiés par la fonction
duck typing#
il n’y a pas de typage statique en Python: on ne sait pas de quel type doivent être x et y, et tant que ça fait du sens au moment de l’exécution, le code est correct ! on appelle ça aussi le duck typing
type hints#
si on le souhaite, on peut indiquer le type des paramètres attendus et du résultat
il faut savoir que c’est totalement optionnel et que ça ne modifie pas le comportement du code
à quoi ça sert du coup, me direz-vous ? eh bien surtout à deux choses
d’abord et surtout à améliorer la documentation et faciliter l’usage de la librairie en question
ensuite et de manière plus optionnelle, on peut utiliser un outil externe appelé type checker comme par exemple mypy qui, lui, va utiliser cette information pour détecter les incohérences entre types attendus et appels effectifs; par contre pour que cette approche soit effective il faut en général que les type hints soient généralisés dans le code…
on reparle plus en profondeur des type hints ici
un objet comme un autre#
pour résumer: des objets normaux
les noms de fonction sont des variables normales
les objets fonction sont des objets comme les autres
voici à nouveau un exemple biscornu; ce n’est évidemment pas recommandé, mais pour bien comprendre, sachez que c’est légal de faire ceci:
l’instuction
return#un appel de fonction est une expression
le résultat de cette expression est spécifié dans le corps de la fonction par l’instruction
returnle premier
returnrencontré provoque la fin de l’exécution de la fonctionsi la fonction se termine sans rencontrer un
returnon retourne
None-Noneest un mot-clé de Python, qui désigne un objet unique (singleton)return et finally (avancé)
returntermine l’exécution de la fonction, sauf si l’expressionreturnse trouve à l’intérieur d’untryavec une clausefinallydans ce cas la clause
finallyest exécutée avant de quitter la fonctionvoir la section sur les exceptions pour comprendre la sémantique de l’instruction
try .. finally