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

Rendez votre code Python plus beau !

Rendez votre code Python plus beau !

Présentation à PyCon FR à Strasbourg.

B06b5d4777e2734feb91298062539ec8?s=128

Ronan Amicel

October 26, 2013
Tweet

Transcript

  1. Rendez votre code Python plus beau ! Ronan Amicel @amicel

    PyCon FR – 25 octobre 2013 – Strasbourg
  2. Ronan Amicel Founder @ PocketSensei ! Hacker in Residence @

    TheFamily
  3. Version originale Raymond Hettinger ! PyCon US 2013 ! Vidéo

    sur pyvideo.org
  4. Du code plus beau ?

  5. Du code plus beau ? • plus simple

  6. Du code plus beau ? • plus simple • plus

    concis
  7. Du code plus beau ? • plus simple • plus

    concis • plus clair
  8. Du code plus beau ? • plus simple • plus

    concis • plus clair • plus idiomatique (== plus « pythonique »)
  9. Du code plus beau ? • plus simple • plus

    concis • plus clair • plus idiomatique (== plus « pythonique ») • plus performant
  10. Itérations

  11. Itérer sur
 un intervalle d’entiers

  12. Itérer sur
 un intervalle d’entiers for i in [0, 1,

    2, 3, 4, 5]:! print i**2
  13. Itérer sur
 un intervalle d’entiers for i in range(6):! print

    i**2 for i in [0, 1, 2, 3, 4, 5]:! print i**2
  14. Itérer sur
 un intervalle d’entiers for i in range(6):! print

    i**2 for i in [0, 1, 2, 3, 4, 5]:! print i**2 for i in xrange(6):! print i**2
  15. Itérer sur
 une collection d'objets

  16. Itérer sur
 une collection d'objets plats = ['choucroute', 'munster', 'kouglof']

  17. Itérer sur
 une collection d'objets plats = ['choucroute', 'munster', 'kouglof']

    for i in range(len(plats)):! print plats[i]
  18. Itérer sur
 une collection d'objets plats = ['choucroute', 'munster', 'kouglof']

    for i in range(len(plats)):! print plats[i] for plat in plats:! print plat
  19. Itérer en partant de la fin

  20. Itérer en partant de la fin plats = ['choucroute', 'munster',

    'kouglof']
  21. Itérer en partant de la fin plats = ['choucroute', 'munster',

    'kouglof'] for i in range(len(plats)-1, -1, -1):! print plats[i]
  22. Itérer en partant de la fin plats = ['choucroute', 'munster',

    'kouglof'] for i in range(len(plats)-1, -1, -1):! print plats[i] for plat in reversed(plats):! print plat
  23. Itérer en maintenant un indice

  24. Itérer en maintenant un indice plats = ['choucroute', 'munster', 'kouglof']

  25. Itérer en maintenant un indice plats = ['choucroute', 'munster', 'kouglof']

    for i in range(len(plats)):! print i, '-->', plats[i]
  26. Itérer en maintenant un indice plats = ['choucroute', 'munster', 'kouglof']

    for i in range(len(plats)):! print i, '-->', plats[i] for i, plat in enumerate(plats):! print i, '-->', plat
  27. Itérer sur deux collections
 en même temps

  28. Itérer sur deux collections
 en même temps vins = ['riesling',

    'edelzwicker', 'gewurztraminer']! plats = ['choucroute', 'munster', 'kouglof']
  29. Itérer sur deux collections
 en même temps vins = ['riesling',

    'edelzwicker', 'gewurztraminer']! plats = ['choucroute', 'munster', 'kouglof'] n = min(len(vins), len(plats))! for i in range(n):! print vins[i], '-->', plats[i]
  30. Itérer sur deux collections
 en même temps vins = ['riesling',

    'edelzwicker', 'gewurztraminer']! plats = ['choucroute', 'munster', 'kouglof'] n = min(len(vins), len(plats))! for i in range(n):! print vins[i], '-->', plats[i] for name, plat in zip(vins, plats):! print name, '-->', plat
  31. Itérer sur deux collections
 en même temps vins = ['riesling',

    'edelzwicker', 'gewurztraminer']! plats = ['choucroute', 'munster', 'kouglof'] n = min(len(vins), len(plats))! for i in range(n):! print vins[i], '-->', plats[i] for name, plat in zip(vins, plats):! print name, '-->', plat for name, plat in izip(vins, plats):! print name, '-->', plat
  32. Itérer sur deux collections
 en même temps vins = ['riesling',

    'edelzwicker', 'gewurztraminer']! plats = ['choucroute', 'munster', 'kouglof'] n = min(len(vins), len(plats))! for i in range(n):! print vins[i], '-->', plats[i] for name, plat in zip(vins, plats):! print name, '-->', plat for name, plat in izip(vins, plats):! print name, '-->', plat from itertools import izip
  33. Itérer selon un ordre de tri

  34. Itérer selon un ordre de tri plats = ['choucroute', 'munster',

    'kouglof']
  35. Itérer selon un ordre de tri plats = ['choucroute', 'munster',

    'kouglof'] for plat in sorted(plats):! print plat
  36. Itérer selon un ordre de tri plats = ['choucroute', 'munster',

    'kouglof'] for plat in sorted(plats):! print plat for plat in sorted(plats, reverse=True):! print plat
  37. Trier selon un critère particulier

  38. Trier selon un critère particulier plats = ['choucroute', 'munster', 'kouglof']

  39. Trier selon un critère particulier plats = ['choucroute', 'munster', 'kouglof']

    def compare_length(c1, c2):! if len(c1) < len(c2):! return -1! if len(c1) > len(c2):! return 1! return 0! ! print sorted(plats, cmp=compare_length)
  40. Trier selon un critère particulier plats = ['choucroute', 'munster', 'kouglof']

    def compare_length(c1, c2):! if len(c1) < len(c2):! return -1! if len(c1) > len(c2):! return 1! return 0! ! print sorted(plats, cmp=compare_length) print sorted(plats, key=len)
  41. Dictionnaires

  42. Itérer sur les clés
 d'un dictionnaire

  43. Itérer sur les clés
 d'un dictionnaire d = {! 'gewurztraminer':

    ‘kouglof',! 'edelzwicker': ‘munster',! 'riesling': ‘choucroute’,! }
  44. Itérer sur les clés
 d'un dictionnaire d = {! 'gewurztraminer':

    ‘kouglof',! 'edelzwicker': ‘munster',! 'riesling': ‘choucroute’,! } for key in d:! print key
  45. Itérer sur les clés
 d'un dictionnaire d = {! 'gewurztraminer':

    ‘kouglof',! 'edelzwicker': ‘munster',! 'riesling': ‘choucroute’,! } for key in d:! print key d = {key: d[key] for key in d if not key.startswith('r')}
  46. Itérer sur les clés et les valeurs d'un dictionnaire

  47. Itérer sur les clés et les valeurs d'un dictionnaire for

    key in d:! print key, '-->', d[key]
  48. Itérer sur les clés et les valeurs d'un dictionnaire for

    key in d:! print key, '-->', d[key] for key, value in d.items():! print key, '-->', value
  49. Itérer sur les clés et les valeurs d'un dictionnaire for

    key in d:! print key, '-->', d[key] for key, value in d.items():! print key, '-->', value for key, value in d.iteritems():! print key, '-->', value
  50. Construire un dictionnaire à partir de paires

  51. Construire un dictionnaire à partir de paires vins = ['riesling',

    'edelzwicker', 'gewurztraminer']! plats = ['choucroute', 'munster', 'kouglof']
  52. Construire un dictionnaire à partir de paires vins = ['riesling',

    'edelzwicker', 'gewurztraminer']! plats = ['choucroute', 'munster', 'kouglof'] d = dict(izip(vins, plats))! {'gewurztraminer': 'kouglof', 'edelzwicker': ‘munster',! 'riesling': 'choucroute'}
  53. Construire un dictionnaire à partir de paires vins = ['riesling',

    'edelzwicker', 'gewurztraminer']! plats = ['choucroute', 'munster', 'kouglof'] d = dict(izip(vins, plats))! {'gewurztraminer': 'kouglof', 'edelzwicker': ‘munster',! 'riesling': 'choucroute'} d = dict(enumerate(vins))! {0: 'riesling', 1: 'edelzwicker', 2: 'gewurztraminer'}
  54. Compter avec des dictionnaires

  55. Compter avec des dictionnaires plats = ['choucroute', 'munster', 'choucroute', ‘kouglof',!

    'munster', 'choucroute']
  56. Compter avec des dictionnaires plats = ['choucroute', 'munster', 'choucroute', ‘kouglof',!

    'munster', 'choucroute'] d = {}! for plat in plats:! if plat not in d:! d[plat] = 0! d[plat] += 1! {'kouglof': 1, 'munster': 2, 'choucroute': 3}
  57. Compter avec des dictionnaires plats = ['choucroute', 'munster', 'choucroute', ‘kouglof',!

    'munster', 'choucroute'] d = {}! for plat in plats:! if plat not in d:! d[plat] = 0! d[plat] += 1! {'kouglof': 1, 'munster': 2, 'choucroute': 3} d = defaultdict(int)! for plat in plats:! d[plat] += 1
  58. Clarifier

  59. Clarifier les appels de fonctions avec des arguments mots-clés

  60. search(‘#pyconfr', False, 20, True) Clarifier les appels de fonctions avec

    des arguments mots-clés
  61. search(‘#pyconfr', False, 20, True) search(‘#pyconfr', retweets=False, numtweets=20, popular=True) Clarifier les

    appels de fonctions avec des arguments mots-clés
  62. Clarifier les valeurs de retour multiples avec des tuples nommés

  63. Clarifier les valeurs de retour multiples avec des tuples nommés

    doctest.testmod()! (0, 4)
  64. Clarifier les valeurs de retour multiples avec des tuples nommés

    doctest.testmod()! (0, 4) doctest.testmod()! TestResults(failed=0, attempted=4)
  65. Clarifier les valeurs de retour multiples avec des tuples nommés

    doctest.testmod()! (0, 4) doctest.testmod()! TestResults(failed=0, attempted=4) from collections import namedtuple! TestResults = namedtuple('TestResults', ['failed', 'attempted'])
  66. « Unpacking »
 de séquences

  67. « Unpacking »
 de séquences p = 'Ronan', 'Amicel', 37,

    '@amicel'
  68. « Unpacking »
 de séquences p = 'Ronan', 'Amicel', 37,

    '@amicel' prenom = p[0]! nom = p[1]! age = p[2]! twitter = p[3]
  69. « Unpacking »
 de séquences p = 'Ronan', 'Amicel', 37,

    '@amicel' prenom = p[0]! nom = p[1]! age = p[2]! twitter = p[3] prenom, nom, age, twitter = p
  70. Performance

  71. Concaténer des chaînes

  72. Concaténer des chaînes vins = ['riesling', 'edelzwicker', 'gewurztraminer',! 'pinot noir',

    'pinot gris', 'muscat', 'sylvaner']
  73. Concaténer des chaînes vins = ['riesling', 'edelzwicker', 'gewurztraminer',! 'pinot noir',

    'pinot gris', 'muscat', 'sylvaner'] s = vins[0]! for name in vins[1:]:! s += ', ' + name! print s
  74. Concaténer des chaînes vins = ['riesling', 'edelzwicker', 'gewurztraminer',! 'pinot noir',

    'pinot gris', 'muscat', 'sylvaner'] s = vins[0]! for name in vins[1:]:! s += ', ' + name! print s print ', '.join(vins)
  75. Décorateurs et
 context managers

  76. Utiliser des décorateurs pour factoriser de la logique

  77. Utiliser des décorateurs pour factoriser de la logique def web_lookup(url,

    saved={}):! if url in saved:! return saved[url]! page = urllib.urlopen(url).read()! saved[url] = page! return page
  78. Utiliser des décorateurs pour factoriser de la logique def web_lookup(url,

    saved={}):! if url in saved:! return saved[url]! page = urllib.urlopen(url).read()! saved[url] = page! return page @cache! def web_lookup(url):! return urllib.urlopen(url).read()
  79. Décorateur cache def cache(func):! saved = {}! ! @wraps(func)! def

    newfunc(*args):! if args in saved:! return newfunc(*args)! result = func(*args)! saved[args] = result! return result! ! return newfunc
  80. Ouvrir et fermer
 des fichiers

  81. Ouvrir et fermer
 des fichiers f = open('data.txt')! try:! data

    = f.read()! finally:! f.close()
  82. Ouvrir et fermer
 des fichiers f = open('data.txt')! try:! data

    = f.read()! finally:! f.close() with open('data.txt') as f:! data = f.read()
  83. Utiliser des locks
 (verrous)

  84. Utiliser des locks
 (verrous) # Créer un lock! lock =

    threading.Lock()
  85. Utiliser des locks
 (verrous) # Créer un lock! lock =

    threading.Lock() # Utiliser un lock (ancienne méthode)! lock.acquire()! try:! print 'Critical section 1'! print 'Critical section 2'! finally:! lock.release()
  86. Utiliser des locks
 (verrous) # Créer un lock! lock =

    threading.Lock() # Utiliser un lock (ancienne méthode)! lock.acquire()! try:! print 'Critical section 1'! print 'Critical section 2'! finally:! lock.release() # Utiliser un lock (nouvelle méthode)! with lock:! print 'Critical section 1'! print 'Critical section 2'
  87. « One liners »

  88. Listes en compréhension et expressions génératrices

  89. Listes en compréhension et expressions génératrices result = []! for

    i in range(10):! s = i ** 2! result.append(s)! print sum(result)
  90. Listes en compréhension et expressions génératrices result = []! for

    i in range(10):! s = i ** 2! result.append(s)! print sum(result) print sum([i**2 for i in xrange(10)])
  91. Listes en compréhension et expressions génératrices result = []! for

    i in range(10):! s = i ** 2! result.append(s)! print sum(result) print sum([i**2 for i in xrange(10)]) print sum(i**2 for i in xrange(10))
  92. Questions ?

  93. Merci !