Upload
ronan-amicel
View
512
Download
1
Embed Size (px)
DESCRIPTION
Présentation à PyCon FR à Strabsourg le 25 octobre 2013.
Citation preview
Rendez votre code Python plus beau !
Ronan Amicel @amicel
PyCon FR – 25 octobre 2013 – Strasbourg
Ronan Amicel
Founder @ PocketSensei !
Hacker in Residence @ TheFamily
Version originale
Raymond Hettinger !
PyCon US 2013 !
Vidéo sur pyvideo.org
Du code plus beau ?
Du code plus beau ?
• plus simple
Du code plus beau ?
• plus simple
• plus concis
Du code plus beau ?
• plus simple
• plus concis
• plus clair
Du code plus beau ?
• plus simple
• plus concis
• plus clair
• plus idiomatique (== plus « pythonique »)
Du code plus beau ?
• plus simple
• plus concis
• plus clair
• plus idiomatique (== plus « pythonique »)
• plus performant
Itérations
Itérer sur un intervalle d’entiers
Itérer sur un intervalle d’entiers
for i in [0, 1, 2, 3, 4, 5]:! print i**2
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
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
Itérer sur une collection d'objets
Itérer sur une collection d'objets
plats = ['choucroute', 'munster', 'kouglof']
Itérer sur une collection d'objets
plats = ['choucroute', 'munster', 'kouglof']
for i in range(len(plats)):! print plats[i]
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
Itérer en partant de la fin
Itérer en partant de la fin
plats = ['choucroute', 'munster', 'kouglof']
Itérer en partant de la fin
plats = ['choucroute', 'munster', 'kouglof']
for i in range(len(plats)-1, -1, -1):! print plats[i]
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
Itérer en maintenant un indice
Itérer en maintenant un indice
plats = ['choucroute', 'munster', 'kouglof']
Itérer en maintenant un indice
plats = ['choucroute', 'munster', 'kouglof']
for i in range(len(plats)):! print i, '-->', plats[i]
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
Itérer sur deux collections en même temps
Itérer sur deux collections en même temps
vins = ['riesling', 'edelzwicker', 'gewurztraminer']!plats = ['choucroute', 'munster', 'kouglof']
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]
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
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
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
Itérer selon un ordre de tri
Itérer selon un ordre de tri
plats = ['choucroute', 'munster', 'kouglof']
Itérer selon un ordre de tri
plats = ['choucroute', 'munster', 'kouglof']
for plat in sorted(plats):! print plat
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
Trier selon un critère particulier
Trier selon un critère particulier
plats = ['choucroute', 'munster', 'kouglof']
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)
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)
Dictionnaires
Itérer sur les clésd'un dictionnaire
Itérer sur les clésd'un dictionnaire
d = {! 'gewurztraminer': ‘kouglof',! 'edelzwicker': ‘munster',! 'riesling': ‘choucroute’,!}
Itérer sur les clésd'un dictionnaire
d = {! 'gewurztraminer': ‘kouglof',! 'edelzwicker': ‘munster',! 'riesling': ‘choucroute’,!}
for key in d:! print key
Itérer sur les clésd'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')}
Itérer sur les clés et les valeurs d'un dictionnaire
Itérer sur les clés et les valeurs d'un dictionnaire
for key in d:! print key, '-->', d[key]
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
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
Construire un dictionnaire à partir de paires
Construire un dictionnaire à partir de paires
vins = ['riesling', 'edelzwicker', 'gewurztraminer']!plats = ['choucroute', 'munster', 'kouglof']
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'}
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'}
Compter avec des dictionnaires
Compter avec des dictionnaires
plats = ['choucroute', 'munster', 'choucroute', ‘kouglof',! 'munster', 'choucroute']
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}
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
Clarifier
Clarifier les appels de fonctions avec des arguments mots-clés
search(‘#pyconfr', False, 20, True)
Clarifier les appels de fonctions avec des arguments mots-clés
search(‘#pyconfr', False, 20, True)
search(‘#pyconfr', retweets=False, numtweets=20, popular=True)
Clarifier les appels de fonctions avec des arguments mots-clés
Clarifier les valeurs de retour multiples avec des tuples nommés
Clarifier les valeurs de retour multiples avec des tuples nommés
doctest.testmod()!(0, 4)
Clarifier les valeurs de retour multiples avec des tuples nommés
doctest.testmod()!(0, 4)
doctest.testmod()!TestResults(failed=0, attempted=4)
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'])
« Unpacking »de séquences
« Unpacking »de séquences
p = 'Ronan', 'Amicel', 37, '@amicel'
« Unpacking »de séquences
p = 'Ronan', 'Amicel', 37, '@amicel'
prenom = p[0]!nom = p[1]!age = p[2]!twitter = p[3]
« 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
Performance
Concaténer des chaînes
Concaténer des chaînes
vins = ['riesling', 'edelzwicker', 'gewurztraminer',! 'pinot noir', 'pinot gris', 'muscat', 'sylvaner']
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
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)
Décorateurs etcontext managers
Utiliser des décorateurs pour factoriser de la logique
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
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()
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
Ouvrir et fermer des fichiers
Ouvrir et fermer des fichiers
f = open('data.txt')!try:! data = f.read()!finally:! f.close()
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()
Utiliser des locks (verrous)
Utiliser des locks (verrous)
# Créer un lock!lock = threading.Lock()
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 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'
« One liners »
Listes en compréhension et expressions génératrices
Listes en compréhension et expressions génératrices
result = []!for i in range(10):! s = i ** 2! result.append(s)!print sum(result)
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)])
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))
Questions ?
Merci !