Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Python the good parts

Python the good parts

Python est un langage de programmation controversé. Il comporte pourtant un tas de qualités ! Les principales sont exposées dans cette présentation.

Romain TOUZE

October 11, 2017
Tweet

More Decks by Romain TOUZE

Other Decks in Technology

Transcript

  1. Dans les boucles et les conditions In [1]: for i

    in range(10): if i % 6 == 0: print("FizzBuzz") elif i % 2 == 0: print("Fizz") elif i % 3 == 0: print("Buzz") else: print(i) FizzBuzz 1 Fizz Buzz Fizz 5 FizzBuzz 7 Fizz Buzz
  2. Dans les classes et les fonctions In [2]: import random

    class Point: def __init__(self, x, y): self.x = x self.y = y def show(self): print("({0}, {1})".format(self.x, self.y)) def show_random_point(): Point(random.randrange(10), random.randrange(10)).show() show_random_point() (3, 6)
  3. Particularités Inférence de type In [9]: In [10]: In [11]:

    In [12]: In [13]: type(1) type("2") type((1, "2")) type([1, 2, 3]) type({"one": 1, "two": 2}) Out[9]: int Out[10]: str Out[11]: tuple Out[12]: list Out[13]: dict
  4. Inférence de type - pas d'interface In [14]: In [15]:

    def add(x, y): return x + y print(add(1, 2)) print(add("foo", "bar")) print(add(1, "bar")) 3 foobar --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-15-b708fb21b54c> in <module>() ----> 1 print(add(1, "bar")) <ipython-input-14-71cdd74d3bce> in add(x, y) 1 def add(x, y): ----> 2 return x + y 3 4 print(add(1, 2)) 5 print(add("foo", "bar")) TypeError: unsupported operand type(s) for +: 'int' and 'str'
  5. Inférence de type : conséquences ? Il faut documenter les

    fonctions, classes et méthodes (avec des docstrings) Il faut exécuter le code, faire des tests unitaires Il y a aujourd'hui la possiblité d'utiliser des et de les véri er avec . annotations de type (https://www.python.org/dev/peps/pep-0484/) mypy (http://mypy- lang.org/)
  6. Les trucs cools Les piles sont incluses Avec la distribution

    standard, vous avez notamment : Un moteur de base de données relationnelle (module sqlite) Le support pour divers type de cher (modules csv, json,...) Un logger (module logging) Un framework de tests unitaire (module unittest) Un pro ler, un debugger...
  7. Et si ça ne su t pas Vous avez des

    milliers de modules sur PyPI (https://pypi.python.org/pypi) pip install pytest
  8. Les trucs cools Les générateurs In [18]: def countdown(start): while

    start > 0: yield start start -= 1 for i in countdown(10): print(i) 10 9 8 7 6 5 4 3 2 1
  9. Les trucs cools La list comprehension In [17]: In [18]:

    In [19]: [i for i in range(10)] [2*i for i in range(10)] [2*i for i in range(10) if i % 3 == 0 ] Out[17]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] Out[18]: [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] Out[19]: [0, 6, 12, 18]
  10. La dict comprehension In [16]: { k:v for k, v

    in zip( ["one", "two", "tree"], ["eins", "zwei", "drei"] ) } # Remarque : les dict sont non ordonnés en Python... Ce ne sera plus le cas en P ython 3.6 ! Out[16]: {'one': 'eins', 'tree': 'drei', 'two': 'zwei'}
  11. Les trucs cools Les décorateurs In [5]: def logged(func): def

    wrapper(*args, **kwargs): print("Appel de {0} avec {1} et {2}".format( func.__name__, str(args), str(kwargs) )) val = func(*args, **kwargs) print("Fin d'appel") return val return wrapper @logged def add(x, y): return x + y add(1, 2) Out[5]: Appel de add avec (1, 2) et {} Fin d'appel 3
  12. Les décorateurs en plus propre In [23]: from functools import

    wraps def logged(func): @wraps(func) def wrapper(*args, **kwargs): print("Appel de {0} avec {1} et {2}".format( func.__name__, str(args), str(kwargs) )) val = func(*args, **kwargs) print("Fin d'appel") return val return wrapper @logged def add(x, y): return x + y print(add.__name__) add
  13. Les trucs cools Les context managers In [7]: class LoggedAdder:

    def __enter__(self): print("Création du LoggedAdder") return self def add(self, x, y): return x + y def __exit__(self, exc_type, exc_value, traceback): print("Fin d'utilisation") with LoggedAdder() as adder: print(adder.add(1, 2)) Création du LoggedAdder 3 Fin d'utilisation
  14. In [9]: with open(r"D:\Workspace\RFF\audit_s3.py") as f: print(f.read()[:100]) #!/usr/bin/env python #

    -*- coding: utf-8 -*- import boto3 s3 = boto3.resource('s3') bucket = s3.B
  15. Les trucs cools Les tests sympathiques In [26]: In [27]:

    a = None if not a: print("None est False") a = "" b = "toto" if not a: print("a est vide") if b: print("b n'est pas vide") None est False a est vide b n'est pas vide
  16. Même sur les listes In [28]: In [29]: In [30]:

    a = [] if not a: print("a est vide") if "bu" in ["ga", "bu", "zo"]: print("J'ai bu") if "bu" in "gabuzo": print("J'ai encore bu") a est vide J'ai bu J'ai encore bu
  17. Fonction ou méthode ? In [2]: class Truc: def __len__(self):

    return 42 t = Truc() print(t.__len__()) print(len(t)) 42 42
  18. Toutes les méthodes commencent par self In [4]: class Machin:

    def __init__(self, value): self.value = value def add(self, val_to_add): self.value += val_to_add def __str__(self): return str(self.value) m = Machin(2) m.add(3) print(m) 5
  19. Les performances Dif cile d'atteindre de hauts niveaux de performances

    Ca reste de l'interprété (pas de JIT) Multithreading limité (Global Interpreter Lock) Toutefois Le niveau de performance est acceptable dans la plupart des cas Il y a des implémentations alternatives (pypy, jython, etc...) Il est possible de coder des extensions en C
  20. In [5]: #pour finir import this The Zen of Python,

    by Tim Peters 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!