>>> import this
Readability counts.
Par Alex Garel pour le Nantes Python Meetup #4
if this == other:
return True
else:
return False
La valeur du test est un booléen, il suffit de le renvoyer !
return this == other
a,b=23, 12
for x in range( 12 ) :
process(x,a = "This is a bit long",
b = i)
value = theBigObject_on_steroids.theProperty_with_a_long_name.Thelong_method(another_long_indentifier*New_object()).am_i_still_in_screen()
Un standard qui veut aider à la lecture du code entre développeurs. flake8 est ton ami.
Si une communauté à d'autres normes, suivez les normes de cette communauté dans vos contributions.
a, b = 23, 12
for x in range(12):
process(
x, a="This is a bit long", b=i)
value = (the_big_object_on_steroids
.the_property_with_a_long_name
.the_long_method(
another_long_indentifier * NewObject())
.am_i_still_in_screen())
if len(my_list) == 0:
print("Oh Gosh, this is empty !")
if len(your_list) > 0:
print("Gimme some !")
Pas besoin de tester la longueur pour savoir qu'une liste est vide.
if not my_list:
print("Oh Gosh, this is empty !")
if your_list:
print("Gimme some !")
def is_empty(a_list):
return a_list
Si une fonction doit renvoyer un booléen, faites le,
bool
est là pour ça
Soyez tolérant dans ce que vous acceptez, exigeant dans ce que vous donnez.d’après Jon Postel
def is_empty(a_list):
return bool(a_list)
# adding value to a query string
# we need to escape the '&'
query_string_list = []
if isinstance(value, str):
try:
param_value = value.replace('&', '%26')
except AttributeError:
param_value = value
query_string_list.append('%s=%s' % (param, param_value))
elif isinstance(value, list):
for subvalue in value:
try:
param_value = subvalue.replace('&', '%26')
except AttributeError:
param_value = subvalue
query_string_list.append('%s=%s' % (param, param_value))
Avant de traiter, normaliser les entrées évite de dupliquer le code et permet de simplifier sa compréhension.
Special cases aren't special enoughzen of python #8
to break the rules
# adding value to a query string
# we need to escape the '&'
query_string_list = []
for param, value in params.items():
if not isinstance(value, list):
value = [value]
for subvalue in value:
param_value = str(subvalue).replace('&', '%26')
query_string_list.append('%s=%s' % (param, param_value))
# swap x and y
temp = y
y = x
x = y
En python on peut directement affecter une valeur a un tuple. On appelle ça unpacking (dépaquetage ?)".
x, y = y, x
circle = (2.0, (1.0, 1.0))
r, (x, y) = circle
import math
def distance((x0, y0), (x1, y1)):
return math.sqrt((x1 - x0)**2 + (y1 - y0)**2)
point1 = (0.0, 0.0)
point2 = (1.0, 1.0)
distance(point1, point2)
Although practicality beats purity.zen of python #9
even_squares = []
for n in range(20):
if n % 2 == 0:
even_squares.append(n ** 2)
Pour une itération simple on peut utiliser les list comprehension.
la syntaxe de certains langages de programmation permet de définir des listes en compréhension, c'est-à-dire des listes dont le contenu est défini par filtrage du contenu d'une autre liste selon un principe analogue à celui de la définition par compréhension de la théorie des ensembles.Wikipedia
even_squares = [n ** 2 for n in range(20) if n % 2 == 0]
Le carré des nombres de 0 à 20 qui sont pairs.
evens = (n for n in range(20) if n % 2 == 0)
even_squares = [n**2 for n in evens]
f = open('path/to/file', 'w')
# lot of maybe failing processing here
f.write('Coucou')
f.close()
Les ContextManager
sont tes amis.
Aussi toujours utiliser open
avec with
.
L'assurance d'un fichier bien fermé !
with open('path/to/file', 'w') as f:
f.write("I feel so smart")
import tempfile
with tempfile.NamedTemporaryFile() as f:
f.write("This message will auto-destruct")
# sorting on values
l = [(v, k) for k, v in my_dict.items()]
l.sort()
l = [(k, v) for k, v in l]
sort
et sorted
acceptent
le paramềtre key
ou cmp
.
Ça fonctionne bien avec lambda, mais également une fonction, hein !
# sorting on values
l = sorted(my_dict.items(), key=lambda e: e[1])
v = values.get(key, None)
w = v is not None and int(v) or v
Pour éviter ce design pattern, les expressions conditionnelles ont été ajoutées en Python 2.5
Ne pas en abuser ! (KISS)
v = values.get(key, None)
w = int(v) if v is not None else v
for i in range(len(my_list)):
elt = my_list[i]
print(i, ': ', elt)
enumerate
renvoie successivement les couples index et élément
d'un itérable.
for i, elt in enumerate(my_list):
print(i, ': ', elt)
On peut aligner nos indexes en utilisant les options de %d
print('% 5d: %s' % (i, elt))
# making an index of text
index = {}
for token in text.split():
letter = token[0]
if letter not in index:
index[letter] = []
index[letter].append(token)
setdefault
permet d'obtenir un élément d'un dictionnaire
ou à défaut de mettre une nouvelle valeur dans le dictionnaire
qui est ensuite retournée.
# making an index of text
index = {}
for token in text.split():
values = index.setdefault(letter, [])
values.append(token)
import random
class ListGenerator(object):
def __init__(self, len):
self.len = len
def generate(self):
return [random.random() for i in range(self.len)]
generator = ListGenerator(len=4)
generator.generate()
Une instance d'objet qui possède une méthode __call__
peut être appelé comme une fonction.
import random
class ListGenerator(object):
def __init__(self, len):
self.len = len
def __call__(self):
return [random.random() for i in range(self.len)]
generator = ListGenerator(len=4)
generator()
def all_factorials(n):
acc = 1
results = []
for i in range(1, n):
acc = acc * i
results.append(acc)
return results
for i in all_factorials(10):
print(i)
Une fonction contentant l'instruction yield
est un générateur sur lequel on peut itérer.
Lorsque l'on demande le nombre suivant, la fonction reprend là où elle s'était arrété.
def all_factorials(n):
acc = 1
for i in range(1, n):
acc = acc * i
yield acc
for i in all_factorials(10):
print(i)
def all_factorials(n):
acc = 1
for i in range(1, n):
acc = acc * i
yield acc
def sqrt(numbers):
for n in numbers:
yield n**0.5
for i in sqrt(all_factorials(10)):
print(i)
class Temperature(object):
def __init__(self, celsius):
self.celsius = celsius
def get_celsius(self):
return self.celsius
def set_celsius(self, v):
self.celsius = v
def get_farenheit(self):
return self.celsius * 1.8 + 32
def set_farefheit(self, v):
self.celsius = (v - 32) / 1.8
t = Temperature(30)
t.get_celsius() # 30
t.set_celsius(3) # chilling
t.get_farenheit() # 37.4
t.set_farenheit(32) # celsius is now 0.0
En python on peut définir des attributs de manière dynamique
via le décorateur property
.
class Temperature(object):
def __init__(self, celsius):
self.celsius = float(celsius)
@property
def farenheit(self):
return self.celsius * 1.8 + 32
@farenheit.setter
def farenheit(self, v):
self.celsius = (v - 32) / 1.8
t = Temperature(30)
t.celsius # 30
t.celsius = 3 # chilling
t.farenheit # 37.4
t.farenheit = 32 # celsius is now 0.0
class ArithTemperature(Temperature):
def add(self, t):
return ArithTemperature(self.celsius + t.celsius)
def substract(self, t):
return ArithTemperature(self.celsius - t.celsius)
def is_zero(self):
return self.celsius == - 273.15
t1 = ArithTemperature(30)
t2 = ArithTemperature(22)
t = t1.add(t2)
print(t.celsius) # 52
t = t1.substract(t2)
print(t.celsius) # 8
t.is_zero() # False
En python on peut surcharger les opérateurs. Dès que ça a du sens, il ne faut pas hésiter !
class ArithTemperature(Temperature):
def __add__(self, t):
return ArithTemperature(self.celsius + t.celsius)
def __sub__(self, t):
return ArithTemperature(self.celsius - t.celsius)
def __nonzero__(self):
return self.celsius != - 273.15
def __str__(self):
return "%d°" % self.celsius
t1 = ArithTemperature(30)
t2 = ArithTemperature(22)
print(t1 + t2) # 52°
t = t1 - t2
print(t) # 8°
bool(t) # True
Python permet d'émuler les types arithmétiques mais aussi
les listes (découpage, accès a un élément, etc…)
les fonctions (voir __call__
)
et plein d'autres choses
Special method names − The with statement
Builtin functions − Builtin types − string − re − datetime − collections − enum − itertools − functools − os.path − shutil − argparse − logging − importlib
Des questions ?