Expressions
Aller au contenu
lambdas
Définition
• Une fonction anonyme
• Qui ne contient qu'une seule expression
• Peut posséder un ou plusieurs arguments
• Qui créent une closure (avec potentiellement des variables liées)
Exemple avec lambdas:
lambda parameters: expression
Equivalent sans lambdas:
def anonymous(parameters):
return expression
Cas d'usages
Fonction qui prend une fonction en paramètre
def get_full_name(first_name, last_name, formatter):
return formatter(first_name, last_name)
On peut l'utiliser comme suit (sans lambdas)
def first_last(first_name, last_name):
return f"{first_name} {last_name}"
def last_first(first_name, last_name):
return f"{last_name}, {first_name}"
full_name = get_full_name('John', 'Doe', first_last)
print(full_name) # John Doe
full_name = get_full_name('John', 'Doe', last_first)
print(full_name) # Doe, John
Ou avec des lambdas:
full_name = get_full_name(
Aller au contenu
'John',
'Doe',
lambda first_name, last_name: f"{first_name} {last_name}"
)
print(full_name)
full_name = get_full_name(
'John',
'Doe',
lambda first_name, last_name: f"{last_name} {first_name}"
)
print(full_name)
Fonction qui retourne une fonction
Définitions
def mult(n):
return lambda x: x * n
Utilisation 1
double = mult(2)
result = double(2)
print(result) ## 4
result = double(3)
print(result) ## 6
Utilisation 2
triple = mult(3)
result = triple(2)
print(result) ## 6
result = triple(3)
print(result) ## 9
Notion de closure (fermeture) et variables liées
• Une fermeture est la paire formée par :
• une fonction
• des références à son état environnant (l'environnement lexical).
• Une fermeture donne accès à la portée d'une fonction externe à partir d'une
Aller au contenu
fonction interne (on dit aussi que la fonction « capture son environnement »).
• Les variables liées sont des références (pointeurs) interne de la closure vers
des variables de l'état environnant.
Warning
Si la valeur de la variable liée à l'extérieur de la closure, cela change de facto la
valeur interne de la variable dans la closure.
Attention aux boucles
Version problématique
callables = []
for i in (1, 2, 3):
[Link](lambda: i)
for f in callables:
print(f())
Version corrigée
callables = []
for i in (1, 2, 3):
[Link](lambda a=i: a)
for f in callables:
print(f())
Note
La version corrigée fonctionne car Python "capture" la valeur de la variable
mentionnée pour la valeur par défaut lors de la définition d'une fonction (c'est à
dire quand la lambda est créée) et pas quand la fonction est exécutée.
Références
• Python Documentation: Lambda Expressions
• W3Schools: Python Lambda
• PythonTutorial: Python Lambda Expressions
• GeeksForGeeks: Python Lambda Functions
Aller au contenu
Gestionnaires
Aller au contenu
de contextes
Définition
• Un objet qui définit un contexte d'execution avec le mot clé with
Exemple
Sans contexte
try:
f = open('[Link]')
data = [Link]()
# convert the number to integer and display it
print(int(data[0]))
except ValueError as error:
print(error)
finally:
[Link]()
Avec contexte
with open('[Link]') as f:
data = [Link]()
print(int(data[0])
Cas d'usages
• Open-Close
• Lock-Release
• Start-Stop
• Change-Reset
Implémentation
Aller au contenu
Context manager protocol
Une instruction with ... est donc équivalente au code suivant:
instance = ContextManager()
ctx = instance.__enter__()
try:
# do something with the txt
finally:
# done with the context
instance.__exit__()
Exemple pour la gestion des fichiers
class File:
def __init__(self, filename, mode):
[Link] = filename
[Link] = mode
def __enter__(self):
print(f'Opening the file {[Link]}.')
self.__file = open([Link], [Link])
return self.__file
def __exit__(self, exc_type, exc_value, exc_traceback):
Aller au contenu
print(f'Closing the file {[Link]}.')
if not self.__file.closed:
self.__file.close()
return False
with File('[Link]', 'r') as f:
print(int(next(f)))
Exemple d'un timer
Définition
from time import perf_counter
class Timer:
def __init__(self):
[Link] = 0
def __enter__(self):
[Link] = perf_counter()
return self
def __exit__(self, exc_type, exc_value, exc_traceback):
[Link] = perf_counter()
[Link] = [Link] - [Link]
return False
Utilisation
def fibonacci(n):
f1 = 1
f2 = 1
for i in range(n-1):
f1, f2 = f2, f1 + f2
return f1
with Timer() as timer:
for _ in range(1, 1000000):
fibonacci(1000)
print([Link])
Références
• ZesteDeSavoir: Gestionnaires de contexte
• Python Context Managers
• RealPython: Context Managers and Python's with Statement
Aller au contenu
• Python Tips: Context Managers
• GeeksForGeeks: Context Manager in Python
Aller au contenu
Iterateurs
Aller au contenu
et générateurs
Définition
L'itérateur permet de :
• manipuler une collection de données,
• c'est à dire parcourir chaque object (sous forme de séquence)
• sans se préoccuper de la structure sous-jacente.
D'un certaine façon c'est un "curseur" que l'on peut déplacer pour pointer un
objet parmis une collection d'objets.
Cas d'usages
• L'itérateur apporte un niveau d'abstraction plus élévé qu'une simple liste
• Changer l'implémentation de la structure de données interne (ex: base de
données, bibliothèque tierce, etc.) tout en gardant un code identique coté
externe
Exemple
Une liste est un iterateur. On peut donc l'utiliser comme suit:
>>> liste = [1,2,3,4,5,6,7,8,9,10]
>>> for x in liste:
... print(x)
Implémentation des iterateurs
Principe
• la fonction iter() : obtenir l'itérateur sur un objet iterable
• la fonction next() : déplace l'itérateur sur l'objet suivant de la collection
Iterateur sur-mesure
Définition
class MonIter():
Aller au contenu
current=0
def __init__(self,stop):
[Link]=stop
def __iter__(self) :
return self
def next(self) :
[Link] += 1
if [Link] > [Link]:
raise StopIteration
if [Link] == 5:
print("Quoi déjà 5eme tour?")
return [Link]
Utilisation
>>> for i in MonIter(50):
... print(i)
...
1
2
3
4
5
Générateurs
Les générateurs permettent de créer plus facilement des itérateurs.
Définition d'un générateur (notez le mot clef yield )
def generateur():
yield "a"
yield "b"
yield "c"
Utilisation d'un générateur
>>> i=generateur()
>>> for v in i:
... print(v)
...
a
b
c
Créons le même itérateur qu'au dessus:
Aller au contenu
def generateur(n):
for i in range(n):
if i == 5:
print "Quoi déjà 5eme tour?"
yield i+1
Utilisons-le:
>>> i=generateur(5)
>>> for v in i:
... print(v)
...
1
2
3
4
5
Références
• [Link]
• [Link]
introduction_iterateurs_generateurs/
Aller au contenu
Décorateurs
Aller au contenu
Définition
Un décorateur est une fonction qui modifie le comportement d'autres fonctions.
Un décorateur est une fonction (ou un callable) qui prend une fonction en
argument et renvoie une fonction de remplacement.
Cas d'usages
Les décorateurs sont utiles lorsque l'on veut ajouter du même code à plusieurs
fonctions existantes, sans avoir à modifier le code d'origine des fonctions.
Syntaxe
Ecriture en python classique
>>> fonction_modifiée = wrapper(fonction_originale)
Ecriture avec le "sucre syntaxique" @
>>> @wrapper
... def fonction_originale(a, b):
... # ...
Note
Le symbole @ applique un décorateur à une fonction
Implémentation
Exemple: une fonction qui s'exécute selon l'utilisateur
user = "john"
def mon_decorateur(fonction_originale):
def autre_fonction():
print "Cet utilisateur n'a pas le droit d'exécuter l'action"
if user <> "john":
return autre_fonction
Aller au contenu
return fonction_originale
@mon_decorateur
def action():
print "Execution des instructions"
• Qu'est ce qui se passe si l'on change le contenu de la variable user ?
Exemple 2 : Décorateur avec gestion des paramètres
def mon_decorateur(fonction):
def autre_fonction(*param, **param2):
print "Début de l'exécution"
fonction(*param, **param2)
print "Fin de l'exécution"
return autre_fonction
@mon_decorateur
def action(v):
print "Execution des instructions %s" % v
Exemple 3 : Empilement de décorateurs
@decorateur1
@decorateur2
def action():
# ...
Exercices
Exercice 1
Créer un décorateur qui limite l'execution d'une fonction :
• Quand la fonction est exécuté trop de fois, une exception est levée.
• Le décorateur doit prend un paramètre qui est le nombre d'execution.
Exercice 2
Créer un décorateur qui contrôle ce que renvoie une fonction : Le décorateur doit
une lever une exception si la fonction renvoie un string ou int.
Exercice 3
Aller au contenu
Un décorateur qui affiche le temps d'execution de la fonction (basique)
Références
• Simeon Franklin: Python Decorators in 12 Steps
• ZesteDeSavoir: Exercice Python - Les décorateurs
• Python Doctor: Les décorateurs Python
Aller au contenu
Métaclasses
Aller au contenu
Définition
• C'est le type d'un type
• L'instruction class crée une instance de métaclasse (ie: une classe)
Rappels sur le types
>>> class Car(object):
... pass
...
>>> automobile = Car()
>>> type(otto)
<class '__main__.Car'>
>>> type(Car)
<class 'type'>
>>> type(type)
<class 'type'>
Exemple simple
>>> type('A', (), {})
<class '__main__.A'>
Exemple avec attributs
La définition classique de classe :
class Car(object):
foo = 'bar'
est équivalente à :
>>> Car = type('Car', (object,), {'foo': 'bar'})
Mais voyons ceci:
>>> A = type('A', (), {'x': 4})
Aller
>>>[Link]
4
>>> A().x
4
>>> type(A)
<class 'type'>
>>> type(A())
<class '__main__.A'>
Equivalent à
class A:
x=4
Exemple plus complet, avec héritage et méthodes.
>>> B = type('B', (int,), {})
>>> B()
0
>>> B = type('B', (int,), {'next': lambda self: self + 1})
>>> B(5).next()
6
>>> def C_prev(self):
... return self - 1
...
>>> C = type('C', (B,), {'prev': C_prev})
>>> C(5).prev()
4
>>> C(5).next()
6
Références
• [Link]
1-types/
• [Link]
2-metaclasses/
• [Link]
• [Link]
Aller au contenu
Modules
Aller au contenu
Définition
• Un module est un ou plusieurs fichier python
• Objectifs :
• Organiser le code Python par thématique ou par domaine de responsabilité
• Permettre la réutilisation de code existant dans d'autres projets ou
d'autres composants
• Définition
• Pypi (package index) et autres
Utilisation
Chargement d'un module
Voir exemple fibonacci de la doc Python officielle.
Importe le module dans l'expace lexical courant
>>> import fibo
>>>
>>> [Link](5)
>>> fibo.fib2(5)
Importe les noms choisis d'un module directement dans l'espace lexical courant
>>> from fibo import fib
>>> fib(...) # ok
>>> fib2(...) # erreur
Importer tous les noms qu'un module définit dans l'espace lexical courant:
>>> from fibo import *
>>> fib(...) # ok
>>> fib2(...) # ok
Identification de l'exécution d'un module
if __name__ == "__main__":
Aller
# au contenu
code qui s'exécute seulement si le fichier chargé directement depuis python
# pas s'il est chargé (indirectement) en tant que module
Référence
• [Link]
Aller au contenu
Utilisation
Aller au contenu
des modules
Installation et désinstallation
Pour installer
pip install package
Pour lister les packages installés
pip list
Pour désinstaller
pip uninstall package
Bonnes pratiques
Utiliser un environnement "bac à sable" pour chaque projet
• Installation de virtualenv avec pip install virtualenv
• Création d'un environnement avec virtualenv venvpath
• Activation de l'environnement avec source bin/activate (depuis le dossier créé)
• Désactivation de l'environnement avec deactivate (fonction shell)
Spécifier les packages nécessaire pour un projet
Lister les dépendances pendant le développement (idealement dans un virtualenv)
pip freeze > [Link]
Installer les dépendances d'un projet (idéalement dans un virtualenv)
pip install -r [Link]
Pipenv : l'outil tout-en-un
Aller au contenu
Démarrage de projet
Créez un nouveau projet en utilisant Python 3.7 :
$ pipenv --python 3.7
Supprime le virtualenv du projet (déduit du répertoire courant) :
$ pipenv --rm
Installer toutes les dépendances pour un projet (les dépendances de dev
s'installent avec l'option --dev ) :
$ pipenv install
Vérifiez que les dépendances installées ne présentent pas de failles de sécurité :
$ pipenv check
Utilisation quotidienne
Pour un shell pré-chargé avec un environnement spécifique (comme l'activation de
virtualenv)
$ pipenv shell
Pour un shell normal, ou les commandes sont exécuté dans le bac à sable au cas
par cas
$ pipenv run COMMAND
Exercices
Exercice 1 : amusons nous avec python
• Utilisation de modules depuis le dépot central
• Voir [Link]
play-with/
Exercice 2 : structurer un projet
Aller au contenu
• Mettre en place un nouveau projet en respectant les bonnes pratiques
Références
• [Link]
• [Link]
• Buildout, an automation tool written in and extended with Python
• Pipenv: Python Development Workflow for Humans
• Buildout
• VirtualEnv
• How to find third-party vulnerabilities in your Python code
Aller au contenu
Création
Aller au contenu
de packages
Etapes
• Structurer son projet de package
• Ecrire les méta-données du package
• Choisir un build-system
• Configurer les méta-données
• Ecrire la documentation ([Link])
• Choisir une licence (LICENSE)
• Créer les archives pour la distribution
• Téléverser le package dans les archives python
Structurer son projet pour un package
Ecrire les méta-données
Choisir un build-system
• Hatchling,
• setuptools
• Flit
• PDM
Dans [Link]
[build-system]
requires = ["hatchling"]
build-backend = "[Link]"
Configurer les méta-données
[project]
name = "example_package_YOUR_USERNAME_HERE"
version = "0.0.1"
authors = [
{ name="Example Author", email="author@[Link]" },
]
description = "A small example package"
readme = "[Link]"
Aller au contenu
license = { file="LICENSE" }
requires-python = ">=3.7"
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
]
[[Link]]
"Homepage" = "[Link]
"Bug Tracker" = "[Link]
Créer les archives pour la distribution
Installation des outils
$ pip install --upgrade build
Génération des fichiers
$ pyproject-build
Résultat
dist/
├── example_package_YOUR_USERNAME_HERE-[Link]
└── example_package_YOUR_USERNAME_HERE-[Link]
Téléverser le package
Aller au contenu
Important
Avant de pouvoir téléverser des packages, il faut commencer par obtenir le droit
d'accéder aux archives
• Créer un compte sur PyPI ou TestPyPI (on va utiliser celui-ci)
• Verifier son adresse email
• Créer un token d'API PyPI depuis la page [Link]
#api-tokens
• Définir le Scope à "Entire Account"
• Garder la page ouverte jusqu'à la configuration complete de twine (car le
token n'est affiché qu'une seule fois)
Installer Twine
$ pip install --upgrade twine
Téléverser les fichiers
$ twine upload --repository testpypi dist/*
Une fois transféré, le package devrait etre disponible sur [Link]
project/example_package_YOUR_USERNAME_HERE .
Important
Twine va demander un username et un password
• Pour le username : __token__
• Pour le password : La valeur du token, en incluant bien le préfixe pypi-
Exercices
Exercice 1 : Texte en couleurs
• création d’un package colorizer
• définir une liste de couleurs
>>> class Color(Enum):
Aller au contenu
... RED="\x1b[31m"
... GREEN="\x1b[32m"
... YELLOW="\x1b[33m"
... BLUE="\x1b[34m"
... RESET="\x1b[0m"
• définir une fonction colorize(string, color) qui retourne une chaine colorisée
• utiliser ce package dans le cadre d'un script
Voir:
• [Link]
• [Link]
Références
• [Link]
• Packaging Python Projects
• Why you shouldn't invoke [Link] directly
Aller au contenu
Définition et historique
Définition
• Les patrons de conception (design patterns) sont des solutions classiques à
des problèmes récurrents de la conception de logiciels.
• Chaque patron est une sorte de plan ou de schéma que vous pouvez
personnaliser afin de résoudre un problème récurrent dans votre code
Intéret
• Les patrons de conception sont une boîte à outils permettant de résoudre des
problèmes classiques de la conception de logiciels.
• Ils définissent un langage commun pour aider votre équipe à communiquer
plus efficacement.
Références
• [Link]
• [Link]
Aller au contenu
Catalogue
Trois types de patrons
• Patrons de création
• fournissent des mécanismes de création d’objets, ce qui augmente la
flexibilité et la réutilisation du code.
• Patrons structurels
• expliquent comment assembler des objets et des classes en de plus
grandes structures, tout en les gardant flexibles et efficaces.
• Patrons comportementaux
• mettent en place une communication efficace et répartissent les
responsabilités entre les objets.
Références
• [Link]
• [Link]
• [Link]
Aller au contenu
Factory & Abstract Factory
• création sous conditions
Références
• [Link]
• [Link]
Aller au contenu
Singleton & dérivés
* maitrise des ressources
Références
• [Link]
• [Link]
python-0d187a73-2f24-4c49-b2aa-bbbf4a45ace6
Aller au contenu
Composite
Références
• [Link]
Aller au contenu
Facade
Références
• [Link]
Aller au contenu
Strategie
Références
• [Link]
Aller au contenu
Iterateur
Références
• [Link]
Aller au contenu
Observateur
Références
• [Link]
Aller au contenu
Chaîne de responsabilité
Références
• [Link]
Aller au contenu
Visiteur
Références
• [Link]