Bienvenue!

Ressources

Read the Source, Luke

Yoda

Pourquoi Python?

Objectifs du language

Permettre de créer des programmes clairs à petite et grande échelle.

Partis pris

Indentation significative

def hello():
    print("Hello")
            

Typage dynamique

toto = "Chaîne"
toto = 42
            

Gestion de la mémoire implicite par comptage de référence

ET garbage collector pour les références cycliques

Philosophie: Le Zen de Python

import this
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

Les différentes implémentations

CPython

Comme son nom l'indique, l'interprêteur est ici écrit en C. Il est compilable sur toutes les plates-formes ou presque

Il s'agit de l'implémentation de référence utilisée par 99% des pythonistes

Le code source python est compilé (de façon transparente) en byte-code universel très proche du code source (.pyc), puis interprêté

Pas d'optimisation dans le byte-code (possibilité d'enlever les assertions)

Pypy

Python en Python.

Contre-intuitivement, cette implémentation permet d'atteindre des performances légèrement meilleures que CPython (dans certains cas)

Grâce à la compilation just-in-time

Forces et faiblesses du language

Faiblesses et comment les contourner

Les performances

CPython étant interprêté ET dynamiquement typé, les performances en calcul brut ne sont pas au niveau du C

On observe en pratique un code 100x (en ordre de grandeur) plus lent que C sur des boucles imbriquées avec calcul arithmétique simple

Mais!

Faiblesses et comment les contourner

La distribution

Chaque programme nécessite d'installer l'interprêteur Python... dans une version compatible avec le programme.

Mais!

Py2exe (sous windows) et freeze (sous linux/mac) permettent de créer des exécutables contenant l'interprêteur + les libs + le programme

Chaque programme embarque son propre interprêteur et librairies. Mais on perd la portabilité, c'est triste

Qui utilise encore des applis lourdes en 2018? N'utilisez pas Python dans ce cas (sauf environnement entreprise)

Faiblesses et comment les contourner

La GIL: Global Interpreter Lock

Python ne permet pas à plusieurs threads d'accéder aux données simultanément. C'est triste

Mais!

On peut utiliser le module standard multiprocessing pour imiter le fonctionnement des threads avec des process.

Cette solution a un surcoût mémoire de plusieurs méga-octets par process Python.

On peut utiliser des systèmes asynchrones distribués basées sur les files d'attentes (queues) telles que RQ ou Celery sur RabbitMQ.

Avec l'avantage dans ce cas de limiter la charge du serveur en pic au prix d'une latence accrue dans les traitements.

Les pièges à éviter

Types mutables

La plupart des types sont immutables, mais certains (list, dict et objets custom) sont mutables

Que fait ce programme?

def append(element, lst=()):
    lst = lst + (element, )
    return lst


print(append(1))
print(append(2))

Que fait ce programme?

def append(element, lst=[]):
    lst.append(element)
    return lst


print(append(1))
print(append(2))

Les pièges à éviter

Python 2

Solution: utiliser Python 3 ;)

Python 2 cesse d'être maintenu en 2020. C'est bientôt

https://pythonclock.org/

lambda

Si votre code utilise lambda dans des situations non-triviales, c'est potentiellement le signe d'un manque de clarté.

lambda peut toujours être remplacé par une vraie fonction. Les fonctions sont des objets comme les autres.

eval

La première règle de l'instruction eval est: on n'utilise pas l'instruction eval.

Utilisez plutôt hasattr, getattr et setattr.

Les pièges à éviter

Collisions de noms

Dans l'example précédent, l'argument lst ne peut pas s'appeler list car c'est un mot-clé réservé en Python.

Python utilise peu de caractères spéciaux et utilise des mots-clés à la place, d'où le risque accru de collision.

On peut contourner ce problème en renommant: on ajoute un _ final.

Dépendances circulaires

On importe un module A depuis un module B qui a lui-même besoin du module A

La solution consiste à retarder le chargement d'un des modules en l'important au plus près de là où on l'utilise (dans la classe ou fonction)

Les forces: Maintenabilité, librairie standard et écosystème

Maintenabilité

Plutôt simple à maintenir, assez peu de code "boilerplate" comme gestion de mémoire

Le code ressemble à ce qu'il fait d'un point de vue "métier"

Les forces: Maintenabilité, librairie standard et écosystème

Librairie standard

La librairie standard est fantastique. Exemples:

Module http: Un serveur web (de fichiers, non sécurisé) en 2 lignes:

from http.server import SimpleHTTPRequestHandler, HTTPServer
HTTPServer(('', 8000), SimpleHTTPRequestHandler).serve_forever()

Module ctypes: appel de printf en quelques lignes:

from ctypes import cdll
libc = cdll.LoadLibrary("libc.so.6")
libc.printf(b"toto %d. But use format instead.\n", 42)

Un bon réflexe avant de développer du code non-métier est de chercher dans la librairie standard, puis les packages PIP.

Les forces: Maintenabilité, librairie standard et écosystème

Écosystème

pip install <package>

Des milliers de packages sont disponibles et installables en 1 commande(un peu comme CPAN pour Perl)

Possibilité d'héberger son propre dépôt PIP privé

Django: framework web extrêmement puissant

Anaconda: Package de modules et d'applications pour le traitement de données en Python:

Requests: Accès au web en mode client. Requêtes HTTP, authentication, cookies, ...

Beautiful Soup: Parsing HTML puissant et élégant

Où et quand utiliser Python plutôt qu'un autre language

N'utilisez pas Python pour des programmes:

Utilisez-le plutôt pour des programmes:

Spécificités propres

La syntaxe

L'indentation est significative

Minimum de symboles cabalistiques (Perl): pas de $, pas de ; en fin de ligne.

Proche du C dans la structure du code: fonctions, boucles, if

Gestion de la mémoire

Fonctionne par comptage de référence. Un objet qui n'est plus accessible est supprimé et la mémoire qu'il occupait est rendue au pool

Toute variable en Python est accédée par référence

Optimisations parfois étranges: les entiers de 0 à 256 sont stockés une seule fois chacun.

Ils sont immutables donc pas de problème a priori

Attention à la comparaison par is cependant:

a=12
b=12
a is b  # True
a=257
b=257
a is b  # False

Les décorateurs

Les décorateurs sont une particularité de Python, permettant de modifier une fonction par une fonction

Proche du concept mathématique de composition: g o f

Pratique pour éviter la duplication, souvent utilisé dans le web:

@login_required
def index(request)
    return 'Hello, world!'
        

Les générateurs et itérateurs

Permet de traiter l'information en mode flux.

Les données traitées n'ont pas besoin d'être résidentes en mémoire => parfait pour le Big Data

docs = get_huge_document_list()
encoded_docs = []
for document in docs:
    encoded_docs.append(doc.encode('rot13'))
return encoded_docs

Cet exemple fonctionne mais alloue temporairement 1)la liste de tous les documents à traiter et 2) la liste des documents traités.

Ces données peuvent dépasser la capacité de mémoire disponible => MemoryError

for document in iter_huge_document_list():
    yield doc.encode('rot13')

Dans ce cas, on alloue au plus 1 document et 1 résultat.

Dans l'idéal, la chaîne de traitement est entièrement composée de générateurs nourrisant des itérateurs.

Si ce n'est pas le cas, on peut convertir simplement un itérateur en liste et vice versa.

Trucs et astuces

Affectations multiples ou swapping

x, y = y, x

Comparaisons multiples

3 < x < 5

Index négatifs

l = [1,2,3]
l[-1] == 3

Mise en pratique

Installation et configuration de CPython 3 et PyCharm

Site Web officiel de la fondation Python: https://www.python.org/

Télécharger Python 3.6 pour Windows: https://www.python.org/ftp/python/3.6.4/python-3.6.4-amd64.exe

Sous Linux:

apt/yum install python3

Sous Mac OS:

brew install python3

Pyenv permet de gérer plusieurs versions de python en parallèle

Virtualenv

Virtualenv crée un environnement séparé contenant l'interprêteur Python + les packages nécessaires à chacune de vos applications

Pycharm

Pycharm Community Edition: https://www.jetbrains.com/pycharm/download/

Pycharm gère vos environnements virtuels et vos packages PIP

Autres IDE

Eclipse + pydev

Sublime text + Anaconda

Maîtrise de l'IDE: Débugger et profiler

Stack trace: Le module traceback

Débuggueur et points d'arrêt

Profile et performance, multi process

Scripting système

Modules os et sys

os.path.join('/home', 'toto') => /home/toto
os.environ => Variables d'environnement dans un dictionnaire
os.listdir() => Liste les fichiers et répertoires du répertoire courant
os.walk() => Liste les fichiers et répertoires sous forme d'arbre
sys.argv => Arguments du programme dans une liste

Déploiement d'applications avec Fabric

Crawler web avec Requests et Beautiful Soup

Mise en pratique avancée

Encodage: Unicode et UTF8

Client MySQL

Multi-threading

Tests unitaires

Créer une API auto-documentée avec Django Rest Framework

Gestion de la mémoire en Python, le compteur de références et le GC

Gardons contact

Sylvain Josserand - [email protected]

intuitivo.fr

Conditions d'utilisation

L'utilisation de ce support et sa copie dans un but non lucratif est autorisée, à condition de conserver cette diapositive.

L'utilisation commerciale de ce support n'est pas autorisée sans mon autorisation préalable. Contactez-moi.

/