diff options
Diffstat (limited to 'fr-fr/python-fr.html.markdown')
| -rw-r--r-- | fr-fr/python-fr.html.markdown | 802 | 
1 files changed, 523 insertions, 279 deletions
| diff --git a/fr-fr/python-fr.html.markdown b/fr-fr/python-fr.html.markdown index 0ae410de..ca510d66 100644 --- a/fr-fr/python-fr.html.markdown +++ b/fr-fr/python-fr.html.markdown @@ -1,293 +1,377 @@  --- -language: python -filename: learnpython-fr.py +language: Python  contributors: -  - ["Louie Dinh", "http://ldinh.ca"] +    - ["Louie Dinh", "http://pythonpracticeprojects.com"] +    - ["Steven Basart", "http://github.com/xksteven"] +    - ["Andre Polykanine", "https://github.com/Oire"] +    - ["Zachary Ferguson", "http://github.com/zfergus2"]  translators: -  - ["Sylvain Zyssman", "https://github.com/sylzys"] -  - ["Nami-Doc", "https://github.com/Nami-Doc"] +    - ["Gnomino", "https://github.com/Gnomino"] +    - ["Julien M'Poy", "http://github.com/groovytron"] +filename: learnpython-fr.py  lang: fr-fr  --- -Python a été créé par Guido Van Rossum au début des années 90. C'est maintenant un des langages de programmation les plus populaires. -Je suis tombé amoureux de Python de par la clarté de sa syntaxe. C'est pratiquement du pseudo-code exécutable. +Python a été créé par Guido Van Rossum au début des années 90. C'est maintenant un des  +langages les plus populaires. Je suis tombé amoureux de Python pour la clarté de sa syntaxe. +C'est tout simplement du pseudo-code exécutable. -Vos retours sont grandement appréciés. Vous pouvez me contacter sur Twitter [@louiedinh](http://twitter.com/louiedinh) ou par e-mail: louiedinh [at] [google's email service] +L'auteur original apprécierait les retours (en anglais): vous pouvez le contacter sur Twitter à [@louiedinh](http://twitter.com/louiedinh) ou par mail à l'adresse louiedinh [at] [google's email service] -N.B. : Cet article s'applique spécifiquement à Python 2.7, mais devrait s'appliquer pour toute version Python 2.x. Python 2.7 est en fin de vie et ne sera plus maintenu à partir de 2020, il est donc recommandé d'apprendre Python avec Python 3. Pour Python 3.x, il existe un autre [tutoriel pour Python 3](http://learnxinyminutes.com/docs/fr-fr/python3-fr/). +Note : Cet article s'applique spécifiquement à Python 3. Jettez un coup d'oeil [ici](http://learnxinyminutes.com/docs/fr-fr/python-fr/) pour apprendre le vieux Python 2.7  ```python -# Une ligne simple de commentaire commence par un dièse -""" Les lignes de commentaires multipes peuvent être écrites -    en utilisant 3 guillemets ("), et sont souvent utilisées -    pour les commentaires + +# Un commentaire d'une ligne commence par un dièse + +""" Les chaînes de caractères peuvent être écrites +    avec 3 guillemets doubles ("), et sont souvent +    utilisées comme des commentaires.  """  #################################################### -## 1. Types Primaires et Opérateurs +## 1. Types de données primaires et opérateurs  #################################################### -# Les nombres -3 #=> 3 - -# Les calculs produisent les résultats mathématiques escomptés -1 + 1 #=> 2 -8 - 1 #=> 7 -10 * 2 #=> 20 -35 / 5 #=> 7 +# On a des nombres +3  # => 3 -# La division est un peu spéciale. C'est une division d'entiers, et Python arrondi le résultat par défaut automatiquement. -5 / 2 #=> 2 - -# Pour corriger ce problème, on utilise les float. -2.0     # Voici un float -11.0 / 4.0 #=> 2.75 ahhh... beaucoup mieux - -# Forcer la priorité avec les parenthèses -(1 + 3) * 2 #=> 8 - -# Les valeurs booléenes sont de type primitif -True -False +# Les calculs sont ce à quoi on s'attend +1 + 1  # => 2 +8 - 1  # => 7 +10 * 2  # => 20 -# Pour la négation, on utilise "not" -not True #=> False -not False #=> True +# Sauf pour la division qui retourne un float (nombre à virgule flottante) +35 / 5  # => 7.0 -# Pour l'égalité, == -1 == 1 #=> True -2 == 1 #=> False +# Résultats de divisions entières tronqués pour les nombres positifs et négatifs +5 // 3     # => 1 +5.0 // 3.0 # => 1.0 # works on floats too +-5 // 3  # => -2 +-5.0 // 3.0 # => -2.0 -# L'inégalité est symbolisée par != -1 != 1 #=> False -2 != 1 #=> True +# Quand on utilise un float, le résultat est un float +3 * 2.0 # => 6.0 -# D'autres comparateurs -1 < 10 #=> True -1 > 10 #=> False -2 <= 2 #=> True -2 >= 2 #=> True +# Modulo (reste de la division) +7 % 3 # => 1 -# On peut enchaîner les comparateurs ! -1 < 2 < 3 #=> True -2 < 3 < 2 #=> False +# Exponentiation (x**y, x élevé à la puissance y) +2**4 # => 16 -# Les chaînes de caractères sont créées avec " ou ' -"C'est une chaîne." -'C\'est aussi une chaîne.' +# Forcer la priorité de calcul avec des parenthèses +(1 + 3) * 2  # => 8 -# On peut aussi les "additioner" ! -"Hello " + "world!" #=> "Hello world!" - -# Une chaîne peut être traitée comme une liste de caractères -"C'est une chaîne"[0] #=> 'C' +# Les valeurs booléennes sont primitives +True +False -# % peut être utilisé pour formatter des chaîne, comme ceci: -"%s can be %s" % ("strings", "interpolated") +# Négation avec not +not True  # => False +not False  # => True + +# Opérateurs booléens +# On note que "and" et "or" sont sensibles à la casse +True and False #=> False +False or True #=> True + +# Utilisation des opérations booléennes avec des entiers : +0 and 2 #=> 0 +-5 or 0 #=> -5 +0 == False #=> True +2 == True #=> False +1 == True #=> True + +# On vérifie une égalité avec == +1 == 1  # => True +2 == 1  # => False + +# On vérifie une inégalité avec != +1 != 1  # => False +2 != 1  # => True + +# Autres opérateurs de comparaison +1 < 10  # => True +1 > 10  # => False +2 <= 2  # => True +2 >= 2  # => True + +# On peut enchaîner les comparaisons +1 < 2 < 3  # => True +2 < 3 < 2  # => False + +# (is vs. ==) is vérifie si deux variables pointent sur le même objet, mais == vérifie +# si les objets ont la même valeur. +a = [1, 2, 3, 4] # a pointe sur une nouvelle liste, [1, 2, 3, 4] +b = a # b pointe sur a +b is a # => True, a et b pointent sur le même objet +b == a # => True, les objets a et b sont égaux +b = [1, 2, 3, 4] # b pointe sur une nouvelle liste, [1, 2, 3, 4] +b is a # => False, a et b ne pointent pas sur le même objet +b == a # => True, les objets a et b ne pointent pas sur le même objet + +# Les chaînes (ou strings) sont créées avec " ou ' +"Ceci est une chaine" +'Ceci est une chaine aussi.' + +# On peut additionner des chaînes aussi ! Mais essayez d'éviter de le faire. +"Hello " + "world!"  # => "Hello world!" +# On peut aussi le faire sans utiliser '+' +"Hello " "world!"  # => "Hello world!" + +# On peut traîter une chaîne comme une liste de caractères +"This is a string"[0]  # => 'T' + +# .format peut être utilisé pour formatter des chaînes, comme ceci: +"{} peuvent etre {}".format("Les chaînes", "interpolées") + +# On peut aussi réutiliser le même argument pour gagner du temps. +"{0} be nimble, {0} be quick, {0} jump over the {1}".format("Jack", "candle stick") +#=> "Jack be nimble, Jack be quick, Jack jump over the candle stick" + +# On peut aussi utiliser des mots clés pour éviter de devoir compter. +"{name} wants to eat {food}".format(name="Bob", food="lasagna") #=> "Bob wants to eat lasagna" + +# Il est également possible d'utiliser les f-strings depuis Python 3.6 (https://docs.python.org/3/whatsnew/3.6.html#pep-498-formatted-string-literals) +name = "Fred" +f"Il a dit que son nom est {name}." #=> "Il a dit que son nom est Fred." + +# Si votre code doit aussi être compatible avec Python 2.5 et moins, +# vous pouvez encore utiliser l'ancienne syntaxe : +"Les %s peuvent être %s avec la %s méthode" % ("chaînes", "interpolées", "vieille") -# Une autre manière de formatter les chaînes de caractères est d'utiliser la méthode 'format' -# C'est la méthode à privilégier -"{0} peut être {1}".format("La chaîne", "formattée") -# On peut utiliser des mot-clés au lieu des chiffres. -"{name} veut manger des {food}".format(name="Bob", food="lasagnes")  # None est un objet -None #=> None +None  # => None -# Ne pas utiliser le symbole d'inégalité "==" pour comparer des objet à None -# Il faut utiliser "is" -"etc" is None #=> False -None is None  #=> True +# N'utilisez pas "==" pour comparer des objets à None +# Utilisez plutôt "is". Cela permet de vérifier l'égalité de l'identité des objets. +"etc" is None  # => False +None is None  # => True -# L'opérateur 'is' teste l'identité de l'objet. -# Ce n'est pas très utilisé avec les types primitifs, mais cela peut être très utile -# lorsque l'on utilise des objets. - -# None, 0, et les chaînes de caractères vides valent False. +# None, 0, and les strings/lists/dicts (chaînes/listes/dictionnaires) valent False lorsqu'ils sont convertis en booléens.  # Toutes les autres valeurs valent True -0 == False  #=> True -"" == False #=> True +bool(0)  # => False +bool("")  # => False +bool([]) #=> False +bool({}) #=> False  ####################################################  ## 2. Variables et Collections  #################################################### -# Afficher du texte, c'est facile -print "Je suis Python. Enchanté!" - +# Python a une fonction print pour afficher du texte +print("I'm Python. Nice to meet you!") -# Il n'y a pas besoin de déclarer les variables avant de les assigner. -some_var = 5    # La convention veut que l'on utilise des minuscules_avec_underscores -some_var #=> 5 +# Par défaut, la fonction print affiche aussi une nouvelle ligne à la fin. +# Utilisez l'argument optionnel end pour changer ce caractère de fin. +print("Hello, World", end="!") # => Hello, World! -# Accéder à une variable non assignée lève une exception -# Voyez les structures de contrôle pour en apprendre plus sur la gestion des exceptions. -some_other_var  # Lève une exception +# Pas besoin de déclarer des variables avant de les définir. +# La convention est de nommer ses variables avec des minuscules_et_underscores +some_var = 5 +some_var  # => 5 -# 'if' peut être utilisé comme expression -"yahoo!" if 3 > 2 else 2 #=> "yahoo!" +# Tenter d'accéder à une variable non définie lève une exception. +# Voir Structures de contrôle pour en apprendre plus sur le traitement des exceptions. +une_variable_inconnue  # Lève une NameError -# Listes +# Les listes permettent de stocker des séquences  li = [] -# On peut remplir liste dès l'instanciation +# On peut initialiser une liste pré-remplie  other_li = [4, 5, 6] -# On ajoute des éléments avec 'append' -li.append(1)    #li contient [1] -li.append(2)    #li contient [1, 2] -li.append(4)    #li contient [1, 2, 4] -li.append(3)    #li contient [1, 2, 4, 3] - -# Et on les supprime avec 'pop' -li.pop()        #=> 3 et li contient [1, 2, 4] -# Remettons-le dans la liste -li.append(3)    # li contient [1, 2, 4, 3] de nouveau. - -# On accède aux éléments d'une liste comme à ceux un tableau. -li[0] #=> 1 -# Le dernier élément -li[-1] #=> 3 - -# Accèder aux indices hors limite lève une exception -li[4] # Lève un 'IndexError' - -# On peut accèder à des rangs de valeurs avec la syntaxe "slice" -# (C'est un rang de type 'fermé/ouvert' pour les plus matheux) -li[1:3] #=> [2, 4] -# Sans spécifier de fin de rang, on "saute" le début de la liste -li[2:] #=> [4, 3] -# Sans spécifier de début de rang, on "saute" la fin de la liste -li[:3] #=> [1, 2, 4] - -# Retirer un élément spécifique dee la liste avec "del" -del li[2] # li contient [1, 2, 3] - -# On peut additionner des listes entre elles -li + other_li #=> [1, 2, 3, 4, 5, 6] - Note: li et other_li existent toujours à part entière +# On ajoute des objets à la fin d'une liste avec .append +li.append(1)    # li vaut maintenant [1] +li.append(2)    # li vaut maintenant [1, 2] +li.append(4)    # li vaut maintenant [1, 2, 4] +li.append(3)    # li vaut maintenant [1, 2, 4, 3] +# On enlève le dernier élément avec .pop +li.pop()        # => 3 et li vaut maintenant [1, 2, 4] +# Et on le remet +li.append(3)    # li vaut de nouveau [1, 2, 4, 3] + +# Accès à un élément d'une liste : +li[0]  # => 1 +# Accès au dernier élément : +li[-1]  # => 3 + +# Accéder à un élément en dehors des limites lève une IndexError +li[4]  # Lève une IndexError + +# On peut accéder à une intervalle avec la syntaxe "slice" +# (c'est un rang du type "fermé/ouvert") +li[1:3]  # => [2, 4] +# Omettre les deux premiers éléments +li[2:]  # => [4, 3] +# Prendre les trois premiers +li[:3]  # => [1, 2, 4] +# Sélectionner un élément sur deux +li[::2]   # =>[1, 4] +# Avoir une copie de la liste à l'envers +li[::-1]   # => [3, 4, 2, 1] +# Pour des "slices" plus élaborées : +# li[debut:fin:pas] + +# Faire une copie d'une profondeur de un avec les "slices" +li2 = li[:] # => li2 = [1, 2, 4, 3] mais (li2 is li) vaut False. + +# Enlever des éléments arbitrairement d'une liste +del li[2]   # li is now [1, 2, 3] + +# On peut additionner des listes +# Note: les valeurs de li et other_li ne sont pas modifiées. +li + other_li   # => [1, 2, 3, 4, 5, 6]  # Concaténer des listes avec "extend()" -li.extend(other_li) # li vaut maintenant [1, 2, 3, 4, 5, 6] +li.extend(other_li)   # Maintenant li contient [1, 2, 3, 4, 5, 6] -# Vérifier l'existence d'un élément dans une liste avec "in" -1 in li #=> True +# Vérifier la présence d'un objet dans une liste avec "in" +1 in li   # => True -# Récupérer la longueur avec "len()" -len(li) #=> 6 +# Examiner la longueur avec "len()" +len(li)   # => 6 -# Les "tuples" sont comme des listes, mais sont immuables. +# Les tuples sont comme des listes mais sont immuables.  tup = (1, 2, 3) -tup[0] #=> 1 -tup[0] = 3  # Lève un 'TypeError' - -# Mais vous pouvez faire tout ceci sur les tuples: -len(tup) #=> 3 -tup + (4, 5, 6) #=> (1, 2, 3, 4, 5, 6) -tup[:2] #=> (1, 2) -2 in tup #=> True - -# Vous pouvez "dé-packager" les tuples (ou les listes) dans des variables -a, b, c = (1, 2, 3)     # a vaut maintenant 1, b vaut maintenant 2 and c vaut maintenant 3 -# Sans parenthèses, un tuple est créé par défaut +tup[0]   # => 1 +tup[0] = 3  # Lève une TypeError + +# Note : un tuple de taille un doit avoir une virgule après le dernier élément, +# mais ce n'est pas le cas des tuples d'autres tailles, même zéro. +type((1))  # => <class 'int'> +type((1,)) # => <class 'tuple'> +type(())   # => <class 'tuple'> + +# On peut utiliser la plupart des opérations des listes sur des tuples. +len(tup)   # => 3 +tup + (4, 5, 6)   # => (1, 2, 3, 4, 5, 6) +tup[:2]   # => (1, 2) +2 in tup   # => True + +# Vous pouvez décomposer des tuples (ou des listes) dans des variables +a, b, c = (1, 2, 3)     # a vaut 1, b vaut 2 et c vaut 3 +# Les tuples sont créés par défaut sans parenthèses  d, e, f = 4, 5, 6 -# Voyez maintenant comme il est facile d'inverser 2 valeurs -e, d = d, e     # d is now 5 and e is now 4 +# Voyez comme il est facile d'intervertir deux valeurs : +e, d = d, e     # d vaut maintenant 5 et e vaut maintenant 4 -# Dictionnaires +# Créer un dictionnaire :  empty_dict = {} -# Un dictionnaire pré-rempli +# Un dictionnaire pré-rempli :  filled_dict = {"one": 1, "two": 2, "three": 3} -# Trouver des valeurs avec [] -filled_dict["one"] #=> 1 +# Note : les clés des dictionnaires doivent être de types immuables. +# Elles doivent être convertibles en une valeur constante pour une recherche rapide. +# Les types immuables incluent les ints, floats, strings et tuples. +invalid_dict = {[1,2,3]: "123"} # => Lève une TypeError: unhashable type: 'list' +valid_dict = {(1,2,3):[1,2,3]}  # Par contre, les valeurs peuvent être de tout type. + +# On trouve une valeur avec [] +filled_dict["one"]   # => 1 + +# On obtient toutes les clés sous forme d'un itérable avec "keys()" Il faut l'entourer +# de list() pour avoir une liste Note: l'ordre n'est pas garanti. +list(filled_dict.keys())   # => ["three", "two", "one"] -# Récupérer toutes les clés sous forme de liste avec "keys()" -filled_dict.keys() #=> ["three", "two", "one"] -# Note - l'ordre des clés du dictionnaire n'est pas garanti. -# Vos résultats peuvent différer de ceux ci-dessus. -# Récupérer toutes les valeurs sous forme de liste avec "values()" -filled_dict.values() #=> [3, 2, 1] -# Note - Même remarque qu'au-dessus concernant l'ordre des valeurs. +# On obtient toutes les valeurs sous forme d'un itérable avec "values()".  +# Là aussi, il faut utiliser list() pour avoir une liste. +# Note : l'ordre n'est toujours pas garanti. +list(filled_dict.values())   # => [3, 2, 1] -# Vérifier l'existence d'une clé dans le dictionnaire avec "in" -"one" in filled_dict #=> True -1 in filled_dict #=> False -# Chercher une clé non existante lève une 'KeyError' -filled_dict["four"] # KeyError +# On vérifie la présence d'une clé dans un dictionnaire avec "in" +"one" in filled_dict   # => True +1 in filled_dict   # => False -# Utiliser la méthode "get()" pour éviter 'KeyError' -filled_dict.get("one") #=> 1 -filled_dict.get("four") #=> None -# La méthode get() prend un argument par défaut quand la valeur est inexistante -filled_dict.get("one", 4) #=> 1 -filled_dict.get("four", 4) #=> 4 +# L'accès à une clé non-existente lève une KeyError +filled_dict["four"]   # KeyError -# La méthode "setdefault()" permet d'ajouter de manière sécuris une paire clé-valeur dans le dictionnnaire -filled_dict.setdefault("five", 5) #filled_dict["five"] vaut 5 -filled_dict.setdefault("five", 6) #filled_dict["five"] is toujours 5 +# On utilise "get()" pour éviter la KeyError +filled_dict.get("one")   # => 1 +filled_dict.get("four")   # => None +# La méthode get accepte une valeur de retour par défaut en cas de valeur non-existante. +filled_dict.get("one", 4)   # => 1 +filled_dict.get("four", 4)   # => 4 +# "setdefault()" insère une valeur dans un dictionnaire si la clé n'est pas présente. +filled_dict.setdefault("five", 5)  # filled_dict["five"] devient 5 +filled_dict.setdefault("five", 6)  # filled_dict["five"] est toujours 5 -# Les sets stockent ... des sets +# Ajouter à un dictionnaire +filled_dict.update({"four":4}) #=> {"one": 1, "two": 2, "three": 3, "four": 4} +#filled_dict["four"] = 4  # une autre méthode + +# Enlever des clés d'un dictionnaire avec del +del filled_dict["one"]  # Enlever la clé "one" de filled_dict. + + +# Les sets stockent des ensembles  empty_set = set() -# On initialise un "set()" avec tout un tas de valeurs -some_set = set([1,2,2,3,4]) # some_set vaut maintenant set([1, 2, 3, 4]) +# Initialiser un set avec des valeurs. Oui, ça ressemble aux dictionnaires, désolé. +some_set = {1, 1, 2, 2, 3, 4}   # some_set est maintenant {1, 2, 3, 4} + +# Comme les clés d'un dictionnaire, les éléments d'un set doivent être immuables. +invalid_set = {[1], 1} # => Lève une TypeError: unhashable type: 'list' +valid_set = {(1,), 1} -# Depuis Python 2.7, {} peut être utilisé pour déclarer un 'set' -filled_set = {1, 2, 2, 3, 4} # => {1 2 3 4} +# On peut changer un set : +filled_set = some_set -# Ajouter plus d'éléments au set -filled_set.add(5) # filled_set contient maintenant {1, 2, 3, 4, 5} +# Ajouter un objet au set : +filled_set.add(5)   # filled_set vaut maintenant {1, 2, 3, 4, 5} -# Intersection de sets avec & +# Chercher les intersections de deux sets avec &  other_set = {3, 4, 5, 6} -filled_set & other_set #=> {3, 4, 5} +filled_set & other_set   # => {3, 4, 5} -# Union de sets avec | -filled_set | other_set #=> {1, 2, 3, 4, 5, 6} +# On fait l'union de sets avec | +filled_set | other_set   # => {1, 2, 3, 4, 5, 6} -# Différence de sets avec - -{1,2,3,4} - {2,3,5} #=> {1, 4} +# On fait la différence de deux sets avec - +{1, 2, 3, 4} - {2, 3, 5}   # => {1, 4} + +# On vérifie la présence d'un objet dans un set avec in +2 in filled_set   # => True +10 in filled_set   # => False -# Vérifier l'existence d'une valeur dans un set avec "in" -2 in filled_set #=> True -10 in filled_set #=> False  #################################################### -## 3. Structure de contrôle +## 3. Structures de contrôle et Itérables  #################################################### -# Initialisons une variable +# On crée juste une variable  some_var = 5 -# Voici une condition 'if'. L'indentation est significative en Python ! -# Affiche "some_var est inférieur à 10" +# Voici une condition "si". L'indentation est significative en Python! +# Affiche: "some_var is smaller than 10"  if some_var > 10: -    print "some_var est supérieur à 10." -elif some_var < 10:    # La clause elif est optionnelle -    print "some_var iinférieur à 10." -else:           # La clause else également -    print "some_var vaut 10." +    print("some_var is totally bigger than 10.") +elif some_var < 10:    # La clause elif ("sinon si") est optionelle +    print("some_var is smaller than 10.") +else:                  # La clause else ("sinon") l'est aussi. +    print("some_var is indeed 10.")  """ -Les boucles "for" permettent d'itérer sur les listes +Les boucles "for" itèrent sur une liste  Affiche: -    chien : mammifère -    chat : mammifère -    souris : mammifère +    chien est un mammifère +    chat est un mammifère +    souris est un mammifère  """  for animal in ["chien", "chat", "souris"]: -    # On peut utiliser % pour l'interpolation des chaînes formattées -    print "%s : mammifère" % animal +    # On peut utiliser format() pour interpoler des chaînes formattées +    print("{} est un mammifère".format(animal))  """ -"range(number)" retourne une liste de nombres -de 0 au nombre donné +"range(nombre)" retourne un itérable de nombres +de zéro au nombre donné  Affiche:      0      1 @@ -295,10 +379,34 @@ Affiche:      3  """  for i in range(4): -    print i +    print(i) + +""" +"range(debut, fin)" retourne un itérable de nombre +de debut à fin. +Affiche: +    4 +    5 +    6 +    7 +""" +for i in range(4, 8): +    print(i)  """ -Les boucles "while" boucle jusqu'à ce que leur condition ne soit plus vraie +"range(debut, fin, pas)" retourne un itérable de nombres +de début à fin en incrémentant de pas. +Si le pas n'est pas indiqué, la valeur par défaut est 1. +Affiche: +    4 +    6 +    8 +""" +for i in range(4, 8, 2): +    print(i) +""" + +Les boucles "while" bouclent jusqu'à ce que la condition devienne fausse.  Affiche:      0      1 @@ -307,66 +415,135 @@ Affiche:  """  x = 0  while x < 4: -    print x +    print(x)      x += 1  # Raccourci pour x = x + 1 -# Gérer les exceptions avec un bloc try/except - -# Fonctionne pour Python 2.6 et ultérieur: +# On gère les exceptions avec un bloc try/except  try: -    # Utiliser "raise" pour lever une exception -    raise IndexError("This is an index error") +    # On utilise "raise" pour lever une erreur +    raise IndexError("Ceci est une erreur d'index")  except IndexError as e: -    pass    # Pass ne prend pas d'arguments. Généralement, on gère l'erreur ici. +    pass    # Pass signifie simplement "ne rien faire". Généralement, on gère l'erreur ici. +except (TypeError, NameError): +    pass    # Si besoin, on peut aussi gérer plusieurs erreurs en même temps. +else:   # Clause optionelle des blocs try/except. Doit être après tous les except. +    print("Tout va bien!")   # Uniquement si aucune exception n'est levée. +finally: #  Éxécuté dans toutes les circonstances. +    print("On nettoie les ressources ici") + +# Au lieu de try/finally pour nettoyer les ressources, on peut utiliser with +with open("myfile.txt") as f: +    for line in f: +        print(line) + +# Python offre une abstraction fondamentale : l'Iterable. +# Un itérable est un objet pouvant être traîté comme une séquence. +# L'objet retourné par la fonction range() est un itérable. + +filled_dict = {"one": 1, "two": 2, "three": 3} +our_iterable = filled_dict.keys() +print(our_iterable) #=> range(1,10). C'est un objet qui implémente l'interface Iterable + +# On peut boucler dessus +for i in our_iterable: +    print(i)    # Affiche one, two, three + +# Cependant, on ne peut pas accéder aux éléments par leur adresse. +our_iterable[1]  # Lève une TypeError + +# Un itérable est un objet qui sait créer un itérateur. +our_iterator = iter(our_iterable) + +# Notre itérateur est un objet qui se rappelle de notre position quand on le traverse. +# On passe à l'élément suivant avec "next()". +next(our_iterator)  #=> "one" + +# Il garde son état quand on itère. +next(our_iterator)  #=> "two" +next(our_iterator)  #=> "three" + +# Après que l'itérateur a retourné toutes ses données, il lève une exception StopIterator +next(our_iterator) # Lève une StopIteration + +# On peut mettre tous les éléments d'un itérateur dans une liste avec list() +list(filled_dict.keys())  #=> Returns ["one", "two", "three"]  ####################################################  ## 4. Fonctions  #################################################### -# Utiliser "def" pour créer une nouvelle fonction +# On utilise "def" pour créer des fonctions  def add(x, y): -    print "x vaut %s et y vaur %s" % (x, y) -    return x + y    # Renvoi de valeur avec 'return' +    print("x est {} et y est {}".format(x, y)) +    return x + y    # On retourne une valeur avec return -# Appeller une fonction avec des paramètres -add(5, 6) #=> Affichet "x is 5 et y vaut 6" et renvoie 11 +# Appel d'une fonction avec des paramètres : +add(5, 6)   # => affiche "x est 5 et y est 6" et retourne 11 -# Une autre manière d'appeller une fonction, avec les arguments -add(y=6, x=5)   # Les arguments peuvent venir dans n'importe quel ordre. +# Une autre manière d'appeler une fonction : avec des arguments +add(y=6, x=5)   # Les arguments peuvent être dans n'importe quel ordre. -# On peut définir une foncion qui prend un nombre variable de paramètres +# Définir une fonction qui prend un nombre variable d'arguments  def varargs(*args):      return args -varargs(1, 2, 3) #=> (1,2,3) +varargs(1, 2, 3)   # => (1, 2, 3) - -# On peut également définir une fonction qui prend un nombre -# variable d'arguments +# On peut aussi définir une fonction qui prend un nombre variable de paramètres.  def keyword_args(**kwargs):      return kwargs -# Appelons-là et voyons ce qu'il se passe -keyword_args(big="foot", loch="ness") #=> {"big": "foot", "loch": "ness"} +# Appelons la pour voir ce qu'il se passe : +keyword_args(big="foot", loch="ness")   # => {"big": "foot", "loch": "ness"} + -# On peut faire les deux à la fois si on le souhaite +# On peut aussi faire les deux à la fois :  def all_the_args(*args, **kwargs): -    print args -    print kwargs +    print(args) +    print(kwargs)  """  all_the_args(1, 2, a=3, b=4) affiche:      (1, 2)      {"a": 3, "b": 4}  """ -# En appellant les fonctions, on peut faire l'inverse des paramètres / arguments ! -# Utiliser * pour développer les paramètres, et ** pour développer les arguments -params = (1, 2, 3, 4) -args = {"a": 3, "b": 4} -all_the_args(*args) # equivaut à foo(1, 2, 3, 4) -all_the_args(**kwargs) # equivaut à foo(a=3, b=4) -all_the_args(*args, **kwargs) # equivaut à foo(1, 2, 3, 4, a=3, b=4) +# En appelant des fonctions, on peut aussi faire l'inverse : +# utiliser * pour étendre un tuple de paramètres  +# et ** pour étendre un dictionnaire d'arguments. +args = (1, 2, 3, 4) +kwargs = {"a": 3, "b": 4} +all_the_args(*args)   # équivalent à foo(1, 2, 3, 4) +all_the_args(**kwargs)   # équivalent à foo(a=3, b=4) +all_the_args(*args, **kwargs)   # équivalent à foo(1, 2, 3, 4, a=3, b=4) + +# Retourne plusieurs valeurs (avec un tuple) +def swap(x, y): +    return y, x # Retourne plusieurs valeurs avec un tuple sans parenthèses. +                # (Note: on peut aussi utiliser des parenthèses) + +x = 1 +y = 2 +x, y = swap(x, y) # => x = 2, y = 1 +# (x, y) = swap(x,y) # Là aussi, rien ne nous empêche d'ajouter des parenthèses + +# Portée des fonctions : +x = 5 + +def setX(num): +    # La variable locale x n'est pas la même que la variable globale x +    x = num # => 43 +    print (x) # => 43 + +def setGlobalX(num): +    global x +    print (x) # => 5 +    x = num # la variable globale x est maintenant 6 +    print (x) # => 6 + +setX(43) +setGlobalX(6) +  # Python a des fonctions de première classe  def create_adder(x): @@ -375,67 +552,78 @@ def create_adder(x):      return adder  add_10 = create_adder(10) -add_10(3) #=> 13 +add_10(3)   # => 13 -# Mais également des fonctions anonymes -(lambda x: x > 2)(3) #=> True +# Mais aussi des fonctions anonymes +(lambda x: x > 2)(3)   # => True +(lambda x, y: x ** 2 + y ** 2)(2, 1) # => 5 -# On trouve aussi des fonctions intégrées plus évoluées -map(add_10, [1,2,3]) #=> [11, 12, 13] -filter(lambda x: x > 5, [3, 4, 5, 6, 7]) #=> [6, 7] +# TODO - Fix for iterables +# Il y a aussi des fonctions de base +map(add_10, [1, 2, 3])   # => [11, 12, 13] +map(max, [1, 2, 3], [4, 2, 1])   # => [4, 2, 3] -# On peut utiliser la syntaxe des liste pour construire les "maps" et les "filters" -[add_10(i) for i in [1, 2, 3]]  #=> [11, 12, 13] -[x for x in [3, 4, 5, 6, 7] if x > 5] #=> [6, 7] +filter(lambda x: x > 5, [3, 4, 5, 6, 7])   # => [6, 7] + +# On peut utiliser les compréhensions de listes pour de jolies maps et filtres. +# Une compréhension de liste stocke la sortie comme une liste qui peut elle même être une liste imbriquée. +[add_10(i) for i in [1, 2, 3]]  # => [11, 12, 13] +[x for x in [3, 4, 5, 6, 7] if x > 5]   # => [6, 7]  ####################################################  ## 5. Classes  #################################################### -# Une classe est un objet -class Human(object): -    # Un attribut de classe. Il est partagé par toutes les instances de cette classe. +# On utilise l'opérateur "class" pour définir une classe +class Human: + +    # Un attribut de la classe. Il est partagé par toutes les instances de la classe.      species = "H. sapiens" -    # Initialiseur basique +    # L'initialiseur de base. Il est appelé quand la classe est instanciée. +    # Note : les doubles underscores au début et à la fin sont utilisés pour +    # les fonctions et attributs utilisés par Python mais contrôlés par l'utilisateur. +    # Les méthodes (ou objets ou attributs) comme: __init__, __str__, +    # __repr__ etc. sont appelés méthodes magiques. +    # Vous ne devriez pas inventer de noms de ce style.      def __init__(self, name): -        # Assigne le paramètre à l'attribut de l'instance de classe. +        # Assigner l'argument à l'attribut de l'instance          self.name = name -    # Une méthode de l'instance. Toutes les méthodes prennent "self" comme 1er paramètre. +    # Une méthode de l'instance. Toutes prennent "self" comme premier argument.      def say(self, msg): -       return "%s: %s" % (self.name, msg) +        return "{name}: {message}".format(name=self.name, message=msg) -    # Une méthode de classe est partagée par toutes les instances. -    # On les appelle avec le nom de la classe en premier paramètre +    # Une méthode de classe est partagée avec entre les instances +    # Ils sont appelés avec la classe comme premier argument      @classmethod      def get_species(cls):          return cls.species -    # Une méthode statique est appellée sans référence à une classe ou à une instance  +    # Une méthode statique est appelée sans référence à une instance ni à une classe.      @staticmethod      def grunt():          return "*grunt*" -# Instancier une classe +# Instantier une classe  i = Human(name="Ian") -print i.say("hi")     # Affiche "Ian: hi" +print(i.say("hi"))     # affiche "Ian: hi"  j = Human("Joel") -print j.say("hello")  #Affiche "Joel: hello" +print(j.say("hello"))  # affiche "Joel: hello"  # Appeller notre méthode de classe -i.get_species() #=> "H. sapiens" +i.get_species()   # => "H. sapiens"  # Changer les attributs partagés  Human.species = "H. neanderthalensis" -i.get_species() #=> "H. neanderthalensis" -j.get_species() #=> "H. neanderthalensis" +i.get_species()   # => "H. neanderthalensis" +j.get_species()   # => "H. neanderthalensis"  # Appeller la méthode statique -Human.grunt() #=> "*grunt*" +Human.grunt()   # => "*grunt*"  #################################################### @@ -444,45 +632,101 @@ Human.grunt() #=> "*grunt*"  # On peut importer des modules  import math -print math.sqrt(16) #=> 4.0 +print(math.sqrt(16))  # => 4.0 -# Et récupérer des fonctions spécifiques d'un module +# On peut importer des fonctions spécifiques d'un module  from math import ceil, floor -print ceil(3.7)  #=> 4.0 -print floor(3.7) #=> 3.0 +print(ceil(3.7))  # => 4.0 +print(floor(3.7))   # => 3.0 -# Récuperer toutes les fonctions d'un module -# Attention, ce n'est pas recommandé. +# On peut importer toutes les fonctions d'un module +# Attention: ce n'est pas recommandé.  from math import * -# On peut raccourcir le nom d'un module +# On peut raccourcir un nom de module  import math as m -math.sqrt(16) == m.sqrt(16) #=> True +math.sqrt(16) == m.sqrt(16)   # => True -# Les modules Python sont juste des fichiers Python ordinaires. -# On peut écrire ses propres modules et les importer. -# Le nom du module doit être le même que le nom du fichier. +# Les modules Python sont juste des fichiers Python. +# Vous pouvez écrire les vôtres et les importer. Le nom du module +# est le nom du fichier. -# On peut trouver quelle fonction et attributs déterminent un module +# On peut voir quels fonctions et objets un module définit  import math  dir(math) +#################################################### +## 7. Avancé +#################################################### + +# Les générateurs aident à faire du code paresseux (lazy) +def double_numbers(iterable): +    for i in iterable: +        yield i + i + +# Un générateur crée des valeurs à la volée. +# Au lieu de générer et retourner toutes les valeurs en une fois, il en crée une à chaque +# itération.  Cela signifie que les valeurs supérieures à 30 ne seront pas traîtées par +# double_numbers. +# Note : range est un générateur aussi.  +# Créer une liste 1-900000000 prendrait beaucoup de temps +# On met un underscore à la fin d'un nom de variable normalement réservé par Python. +range_ = range(1, 900000000) +# Double tous les nombres jusqu'à ce qu'un nombre >=30 soit trouvé +for i in double_numbers(range_): +    print(i) +    if i >= 30: +        break + + +# Decorateurs +# Dans cet exemple, beg enveloppe say +# Beg appellera say. Si say_please vaut True le message retourné sera changé +from functools import wraps + + +def beg(target_function): +    @wraps(target_function) +    def wrapper(*args, **kwargs): +        msg, say_please = target_function(*args, **kwargs) +        if say_please: +            return "{} {}".format(msg, "Please! I am poor :(") +        return msg + +    return wrapper + + +@beg +def say(say_please=False): +    msg = "Can you buy me a beer?" +    return msg, say_please + + +print(say())  # affiche Can you buy me a beer? +print(say(say_please=True))  # affiche Can you buy me a beer? Please! I am poor :(  ``` -## Prêt à aller plus loin? +## Prêt pour encore plus ? -### En ligne gratuitement +### En ligne et gratuit (en anglais) +* [Automate the Boring Stuff with Python](https://automatetheboringstuff.com)  * [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)  * [Dive Into Python](http://www.diveintopython.net/) -* [The Official Docs](http://docs.python.org/2.6/) +* [Ideas for Python Projects](http://pythonpracticeprojects.com) +* [The Official Docs](http://docs.python.org/3/)  * [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/) -* [Python Module of the Week](http://pymotw.com/2/) +* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182) +* [Python Course](http://www.python-course.eu/index.php) +* [First Steps With Python](https://realpython.com/learn/python-first-steps/) + +### En ligne et gratuit (en français) -### Format papier +* [Le petit guide des batteries à découvrir](https://he-arc.github.io/livre-python/) + +### Livres (en anglais)  * [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20)  * [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20)  * [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20) - | 
