.. $Id: documentation.rst.in 14117 2011-05-11 08:12:37Z ycadour $ .. _Python: http://www.python.org .. index:: syntaxe ################### Syntaxe du language ################### La syntaxe du langage python est connue pour être - Simple - Concise - Efficace .. index:: indentation ============= L'indentation ============= Une des caractéristiques du langage Python_ est l'utilisation des indentations comme structuration des programmes. Exemples: >>> word = 'bonjour' >>> for letter in word: ... print(letter) ... b o n j o u r L'interpréteur détermine le nombre d'espace au début de chaque ligne et en déduit le niveau d'indentation. Une mauvaise indentation peut provoquer une erreur syntaxique. :: >>> for letter in 'Bonjour': ... print(letter) File "", line 2 print(letter) ^ IndentationError: expected an indented block Par convention on utilise 4 caractères d'espacement pour une indentation. **Cette caractéristique du langage permet d'obtenir un code forcément bien indenté puisque l'indentation fait partie intégrante du langage.** .. index:: commentaires ================ Les commentaires ================ Les commentaires sont préfixés par le caractère dièse '#' et peuvent être placés en fin de ligne ou prendre une ligne complète. :: >>> a = 'Bonjour' #Ceci est une affectation variable >>> # Maintenant j'affiche la variable ... print(a) Bonjour .. index:: types ==================== Les différents types ==================== -------------------- Les types numériques -------------------- Il en existe 3 types: - Les entiers (simple ou long) - Les valeurs à virgule flottante - Les nombres complexes .. index:: int, entier Les entiers ########### - Les entiers sont des nombres qui s'étendent sur une machine 32 bits entre les valeurs -2e31+1 et 2e31-1, soit entre -2147483647 et 2147483647. - Pour obtenir un nombre négatif on le préfixe du signe '-' Les différentes bases: - La forme décimale commence par un chiffre de 1 à 9 suivi de chiffre de 0 à 9. - La base octale commence par '0' suivi de chiffres de 0 à 7. - La base hexadécimale commence par '0x' suivi de chiffres 0 à 9 et de lettres de A à F. Les entiers longs - Les entiers longs sont eux limités uniquement par la capacité mémoire de la machine. - Ils sont représentés de la même manière que les entiers mais sont suffixés de la lettre L. - Depuis la version de 2.4 un nombre entier est automatiqument transtypé si il dépasse la plage autorisée. :: >>> x = 1 >>> type(x) >>> x = 10000000000000000000000000000000000000000 >>> type(x) .. index:: float, flottant Les flottants ############# - Les flottants permettent de représenter des nombres réels. - La partie entière est séparée de la partie fractionnelle par un '.' :: >>> x = 1.0 >>> type(x) >>> x = 1. >>> x = 0.1 >>> x = .1 >>> x = -09.02 >>> x = -9.02 .. index:: complexe Les nombres complexes ##################### :: >>> a = 2 + 1j >>> b = 1 + 2j >>> a+b (3+3j) >>> a.imag 1.0 >>> a.real 2.0 >>> a.conjugate() (2-1j) .. index:: séquence ------------- Les séquences ------------- **Une séquence est une collection ordonnée d'éléments indexés par des nombres positifs.** Les index varient de 0 à n-1 pour une séquence de n éléments. Pour accéder à l'élement qui se trouve en position i on opére de la manière suivante: **sequence[i-1]** +-------+-------+-------+-----------+-------+-------+ | el1 | el2 | | **eli** | | eln | +=======+=======+=======+===========+=======+=======+ | 0 | 1 | | **i-1** | | n-1 | +-------+-------+-------+-----------+-------+-------+ On peut utiliser des nombres négatifs en les faisant varier de -1 à -n : **sequence[-2]** +-------+-------+-------+-----------+-------+ | el1 | el2 | | **eln-1** | eln | +=======+=======+=======+===========+=======+ | -n | -n+1 | | **-2** | -1 | +-------+-------+-------+-----------+-------+ Les séquences peuvent être coupées en tranches qui forment alors des sous séquences. sequence[i,j] forme la sequence de l'élement i inclus jusqu'à l'élément j exclu : **sequence[1:3]** +-------+---------+---------+---------+---------+---------+ | el1 | **el2** | **el3** | el4 | | eln | +=======+=========+=========+=========+=========+=========+ | 0 | **1** | **2** | 3 | | | +-------+---------+---------+---------+---------+---------+ **sequence[0:-1]** +---------+---------+---------+---------+---------+---------+---------+ | **el1** | **el2** | **el3** | **el4** | |**eln-1**| eln | +=========+=========+=========+=========+=========+=========+=========+ | **0** | **1** | **2** | **3** | | **-2** | -1 | +---------+---------+---------+---------+---------+---------+---------+ - sequence[:-1] <=> sequence[0:-1] - sequence[1:] <=> sequence[1:n] Il existe un troisième élement qui permet de faire varier le pas. **sequence[0:-1:2]** +-------+---------+---------+---------+---------+ |**el1**| el2 | **el3** | el4 | | +=======+=========+=========+=========+=========+ |**0** | 1 | **2** | 3 | | +-------+---------+---------+---------+---------+ sequence[::-1] => inverse l'ordre de la séquence Quelques primitives qui s'appliquent sur les séquences: - *len()* : retourne le nombre d'élements de la séquence - *min()*, *max()* : renvoie respectivement l'élement à valeur minimale et maximale de la séquence - *sum()* : renvoie la somme des élements lorsque ceux ci sont additionnables. En python il existe 4 types de séquences: - Les strings - Les unicode - Les listes - Les tuples Il existe 2 grandes familles de séquences, les **séquences immuables** (string, unicode et tuple) et les **séquences modifiables** (liste). .. index:: string, chaîne de caractères Les bytes (ex string python 2) ############################### Les *bytes* sont des valeurs alphanumériques, elles sont entourées de guillemets simples ou doubles ou de 3 guillemets simples ou doubles et préfixées par un b. Elles sont toujours encodées. :: >>> a = b'hello' >>> b = b"hello" >>> c = b'''hello''' >>> d = b"""hello""" Un byte est une **séquence ordonnée** d'éléments. **Un byte n'est plus modifiable une fois instanciée**. Les *byte* sont des séquences de caractères. Par défaut, chaque caractère est codé sur 8 bits ce qui correspond à des valeurs de 0 à 255. Les valeurs de 0 à 127 sont les caractères de la tables ASCII ceux de 128 à 255 les caractères de la table ASCII étendue. **Il n'existe pas en python de type caractère**, un caractère est un byte de longueur 1. En python 2, les strings sont portés par l'ancienne classe: *les strings*. Quelques primitives du langage sur les strings :: >>> chr(120) 'x' >>> ord(b'x') 120 Les bytes sont des séquences, les différents éléments sont accessibles comme décrit plus haut: :: >>> mot = b'hello' >>> mot[1] '101' Les bytes sont des séquences immuables, leurs valeurs ne sont donc pas modifiables. :: >>> mot[1] = b'a' Traceback (most recent call last): File "", line 1, in TypeError: 'bytes' object does not support item assignment Méthodes sur les bytes ======================== :: >>> mot = b'Hello' >>> dir(mot) ['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__','__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_formatter_field_name_split', 'capitalize', 'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace', 'istitle','isupper', 'join', 'ljust', 'lower', 'lstrip', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill'] **Exercice:Créer une string et essayer quelques méthodes.** Voir en particulier les méthodes *split* et *join*. .. index:: unicode Les strings (ex unicode) ####################### Le type *str* fonctionne de la même façon mais sur une plage de 32 bits. Ils sont standards en python 3.x. (format encodage utilisé par défaut). >>> unichr(16000) u'\u3e80' >>> print(unichr(16000)) 㺀 >>> ord('€') 8364 La conversion entre *bytes* et *strings** est possible grâce aux méthodes encode et décode, puique la relation ne peut être bijective on utilise un codec qui permet d'établir la correspondance entre les deux. :: >>> encode = 'é'.encode('ISO-8859-15') >>> print(encode) é >>> decode='é'.encode('ISO-8859-15').decode('ISO-8859-15') >>> print(decode) é Formatage des chaines de caractères (strings ou bytes) :: >>> firstname = 'John' >>> lastname = 'Cleese' >>> print("Hello {}".format(firstname)) Hello John >>> print("Hello {0} {1}".format(firstname, lastname)) Hello John Cleese Il existe certaines expression pour modifier la valeur de l'argument. Exemple, pour les float, la syntaxe est .[P]f où P est un paramètre optionnel qui précise la précion utilisée. :: >>> pi = 3.14141592654 >>> print ("pi vaut {:.2f}".format(pi)) >>> print ("pi vaut {0:.2f}".format(pi)) :: >>> pi = 3.14141592654 >>> print ("pi vaut {:.2f}".format(pi)) >>> print ("pi vaut {0:.2f}".format(pi)) D'autres méthodes de formatage existent, mais elles sont à proscrire: :: >>> firstname = 'John' >>> lastname = 'Cleese' >>> print("Hello %s" % firstname) Hello John >>> print("Hello %s %s" % (firstname,lastname)) Hello John Cleese *TODO: utiliser la méthode format avec quelques exemples* .. index:: tuple Les tuples ########## **Les tuples sont des séquences qui contiennent des éléments qui peuvent être hétérogènes.** Un tuple est encadré par des parenthèses et chaque élément est séparé par une virgule. **Une fois créé il est impossible de modifier sa valeur.** :: >>> actors = ('John Cleese', 'Terry Gilliam', 'Michael Palin') >>> heterogene = ('John Cleese', 2, u'Terry Gilliam') >>> len(actors) 3 >>> actors[1] 'Terry Gilliam' >>> actors[1] = 'Terry Jones' Traceback (most recent call last): File "", line 1, in TypeError: 'tuple' object does not support item assignment .. index:: list Les listes ########## **Les listes sont des séquences d'élements qui peuvent être hétérogènes et dont la valeur peut être modifiée après sa création.** Une liste est encadrée par des crochets et chaque élément est séparé par une virgule. :: >>> liste_vide = [] >>> actors = ['John Cleese'] >>> len(actors) 1 Voici quelques méthodes qui s'appliquent aux listes. :: >>> dir(actors) ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__delslice__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getslice__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__setslice__', '__sizeof__', '__str__','__subclasshook__', 'append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort'] >>> actors.append('Terry Gilliam') >>> actors ['John Cleese', 'Terry Gilliam'] >>> new_actors = ['Michael Palin', 'Terry Jones'] >>> actors.extend(new_actors) >>> actors ['John Cleese', 'Terry Gilliam', 'Michael Palin', 'Terry Jones'] >>> actors.insert(2, 'Eric Idle') >>> actors ['John Cleese', 'Terry Gilliam', 'Eric Idle', 'Michael Palin', 'Terry Jones'] >>> actors.remove('John Cleese') >>> actors ['Terry Gilliam', 'Eric Idle', 'Michael Palin', 'Terry Jones'] >>> actors.pop(2) 'Michael Palin' >>> actors ['Terry Gilliam', 'Eric Idle', 'Terry Jones'] >>> actors.index('Terry Jones') 2 >>> actors.append(actors[2]) >>> actors ['Terry Gilliam', 'Eric Idle', 'Terry Jones', 'Terry Jones'] >>> actors.count('Terry Jones') 2 >>> actors.sort() >>> actors ['Eric Idle', 'Terry Gilliam', 'Terry Jones', 'Terry Jones'] >>> actors.reverse() >>> actors ['Terry Jones', 'Terry Jones', 'Terry Gilliam', 'Eric Idle'] **Exercice: Créer une liste et essayer certaines méthodes** .. index:: dict, dictionnaire ----------------- Les dictionnaires ----------------- Le mapping, appelé dictionnaire, est une collection d'éléments qui sont identifiés par des clefs uniques. - Un dictionnaire n'est pas ordonné. - Les clefs doivent être des objets immuables (chaines de caractère, entier, flottant...) - Les élements peuvent être hétérogènes Un dictionnaire est encadrée par des accolades, chaque élement est séparé par une virgule, Chaque élement est préfixé par sa clef suivi de ':'. :: >>> dico_vide = {} >>> cleese = {'firstname':'John', 'lastname':'Cleese', 'year_of_birth':1939, 'movies':['Monty Python, la vie de Brian', 'Un poisson nommé wanda']} >>> len(cleese) 4 >>> cleese['firstname'] 'John' Voici quelques méthodes des dictionnaires >>> a = {} >>> dir(a) >>> ['__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values'] Autres exemples de création >>> dict(sape=4139, guido=4127, jack=4098) {'sape': 4139, 'jack': 4098, 'guido': 4127} >>> dict([('sape', 4139), ('guido', 4127), ('jack', 4098)]) {'sape': 4139, 'jack': 4098, 'guido': 4127} **Exercice: Créer un dictionnaire et essayer certaines méthodes** .. index:: set, ensemble ------------------------ Les ensembles (type set) ------------------------ TODO: un conteneur d'objets uniques avec des méthodes permettant de faire des calculs d'intersection, d'union, etc... Un ensemble est encadré par des accolades et chaque élément est séparé par une virgule. :: >>> ensemble = {} #dictionnaire >>> ensemble = {'John Cleese','Terry Gilliam'} # type set >>> len(ensemble) 2 >>> ensemble.update({'John Cleese'}) >>> len(ensemble) 2 ---- None ---- Type à valeur unique qui ne représente une absence de valeur. .. index:: booléen ------------ Les booleans ------------ Représentés par 'True' ou 'False' Tout les types de valeur peuvent être interprétés de manière booléénne +-------------+--------------+---------------------+ | type | False | True | +=============+==============+=====================+ | int | 0 | les autres valeurs | +-------------+--------------+---------------------+ | float | .0 | les autres valeurs | +-------------+--------------+---------------------+ | list | [] | les listes non vides| +-------------+--------------+---------------------+ | tuple | () | les tuples non vides| +-------------+--------------+---------------------+ | dict | {} | les dicts non vides | +-------------+--------------+---------------------+ | noneType | None | X | +-------------+--------------+---------------------+ ------------------ Synthèse des types ------------------ +-------------+-----------------+---------------------+---------------------+ | type | exemple | sequence | modifiable | +=============+=================+=====================+=====================+ | int | 1 | NON | NON | +-------------+-----------------+---------------------+---------------------+ | float | 1.0 | NON | NON | +-------------+-----------------+---------------------+---------------------+ | complex | 1+1j | NON | NON | +-------------+-----------------+---------------------+---------------------+ | unicode | 'Hello' | OUI | NON | +-------------+-----------------+---------------------+---------------------+ | byte | b'Hello' | OUI | NON | +-------------+-----------------+---------------------+---------------------+ | tuple | ('string',1) | OUI | NON | +-------------+-----------------+---------------------+---------------------+ | list | ['string',1] | OUI | OUI | +-------------+-----------------+---------------------+---------------------+ | dict | {'key':'valeur'}| NON | OUI | +-------------+-----------------+---------------------+---------------------+ ----------- Transtypage ----------- +-------------+-----------------+-------------------------------------------+ | primitive | exemple | description | +=============+=================+===========================================+ | str(el) | str(1) => '1' | retourne l'élement sous forme de string | +-------------+-----------------+-------------------------------------------+ | int(el) | int('1') => 1 | retourne l'élement sous forme d'entier | +-------------+-----------------+-------------------------------------------+ | float(el) | float('1')=>1.0 | retourne l'élement sous forme de float | +-------------+-----------------+-------------------------------------------+ | list(el) | list('1')=>['1']| retourne l'élement sous forme de liste | +-------------+-----------------+-------------------------------------------+ | tuple(el) | tuple([1])=>(1,)| retourne l'élement sous forme de tuple | +-------------+-----------------+-------------------------------------------+ .. index:: opérateurs ============== Les opérateurs ============== ---------------------- Les opérateurs de base ---------------------- Addition, soustraction, multiplication, division :: >>> 2+3 5 >>> 3-5 -2 >>> 2*7 14 >>> 'hello'*5 'hellohellohellohellohello' >>> 'hello' + ' ' + 'world' 'hello world' >>> 1/6 0 >>> 1.0/6 0.16666666666666666 ---------------- Autre opérateurs ---------------- Modulo ###### opérateur % :: >>> 10 % 3 1 Négation ######## opérateur - :: >>> a = 10 >>> -a -10 Puissance ######### opérateur ** :: >>> 2 ** 8 256 Appartenance ############ opérateur *in* S'applique à toutes les séquences :: >>> 'y' in 'Terry' True >>> 1 in [0,1,2,3,4] True Opérateurs de comparaison ######################### - < : inférieur strictement - > : supérieur strictement - <= : inférieur ou égal - >= : supérieur ou égal - == : égal - != : différent - is : est - is not : n'est pas Une comparaison travaille sur deux objets et renvoie un résultat **booléen**. Exemple de comparaison de deux strings égales:: Les strings sont immuables, l'affectation mémoire des deux objets est identique:: >>> a = 'Hello' >>> b = 'Hello' >>> id(a) 39756736 >>> id(b) 39756736 >>> a is b True ============================= Les structures conditionnelles ============================= Les structures conditionnelles sont des regroupements de lignes délimitées par un niveau d'indentation et dont le contenu est exécuté en fonction d'une ou plusieurs conditions. .. index:: if ---------------- L'instruction if ---------------- Syntaxe:: if condition: bloc de lignes else: bloc de lignes Exemples:: >>> actors = ['Terry Jones', 'Terry Gilliam', 'Eric Idle'] >>> if 'Terry Jones' in actors: ... print('Terry Jones est dans les acteurs') ... else: ... print('Terry Jones n\'est pas dans les acteurs') ... Terry Jones est dans les acteurs >>> if 'Terry Jones' or 'Eric Idle' in actors: ... print('Il y a Terry Jones ou Eric Idle') ... Il y a Terry Jones ou Eric Idle >>> if 'John Clesse' in actors: ... print('Il y a Terry Jones') ... elif 'Terry Gilliam' in actors: ... print('Il y a Terry Gilliam') ... else: ... print('Il n\'y a ni Terry Gilliam ni Terry Jones') ... Il y a Terry Gilliam .. index:: for..in --------------------- L'instruction for..in --------------------- Syntaxe:: for variable in sequence: bloc de lignes else: bloc de lignes Exemples:: >>> for actor in actors: ... print(actor) ... Terry Jones Terry Gilliam Eric Idle >>> for letter in actors[0]: ... print(letter) ... else: ... print('fini') ... T e r r y J o n e s fini Deux instructions permettent d'influer sur le déroulement de la boucle: - *continue* interrompt l'execution de la boucle pour l'élément en cours et passe à l'élement suivant. - *break* interrompt l'execution de la boucle et n'exécute pas l'instruction else. :: >>> for letter in actors[0]: ... if letter=='e': ... continue ... print(letter) ... T r r y J o n s >>> for actor in actors: ... print(actor) ... if actor == 'Terry Gilliam': ... break ... Terry Jones Terry Gilliam .. index:: while ------------------- L'instruction while ------------------- L'instruction *while* permet d'exécuter un bloc de lignes tant qu'une expression est vérifiée. Si l'expression n'est plus vraie l'instruction estlse est exécutée ci celle ci existe et la boucle s'arrête. Remarque : Les instructions *continue* et *break* peuvent également s'utiliser avec *while* Syntaxe:: while condition: bloc de lignes else: bloc de lignes Exemple:: >>> i = 1 >>> while i < 100: ... i += i ... print i ... 2 4 8 16 32 64 128 .. index:: list comprehensions ======================= Les list comprehensions ======================= Les lists comprehensions donnent un moyen concis d'appliquer une fonction sur chaque élément d'une liste afin d'en produire une nouvelle. Voir http://docs.python.org/tutorial/datastructures.html#list-comprehensions Exemples: :: >>> nombres = [1,3,8,9,7,32,89,42] >>> # retourner sous forme de liste chacun des nombres au carré >>> [nombre*nombre for nombre in nombres] [1, 9, 64, 81, 49, 1024, 7921, 1764] >>> nombres = [1,3,8,9,7,32,89,42] >>> # retourner sous forme de liste les nombres pairs >>> [nombre for nombre in nombres if nombre%2==0] [8, 32, 42] .. index:: dict comprehensions ======================= Les dict comprehensions ======================= Les dict comprehensions donnent un moyen concis de créer un dictionnaire à partir d'une itération. Exemples: :: >>> {x: x**2 for x in (2, 4, 6)} {2: 4, 4: 16, 6: 36} .. index:: exceptions ========== Exceptions ========== Une exception est lévée lorsque les conditions d'execution du programme ne sont pas respectées. L'exception la plus emblématique est la division par zéro :: >>> 1/0 Traceback (most recent call last): File "", line 1, in ZeroDivisionError: integer division or modulo by zero .. index:: try..except..else ----------------- try..except..else ----------------- Lorsqu'une exception est levée il est possible de la stopper en interceptant l'erreur. syntaxe :: try: bloc de code surveillé except: bloc de code exécuté si l'exception est levée :: >>> def division(a,b): ... try: ... return a/b ... except: ... return 'infini' ... >>> division(4,0) 'infini' >>> division('allo',0) 'infini' Il est fortement conseillé de spécifier l'exception afin de ne pas masquer silencieusement tous les types d'erreur qui pourrait intervenir. :: >>> def division(a,b): ... try: ... return a/b ... except ZeroDivisionError: ... return 'infini' ... >>> division(4,0) 'infini' >>> division('allo',0) Traceback (most recent call last): File "", line 1, in File "", line 3, in division TypeError: unsupported operand type(s) for /: 'str' and 'int' Il est possible d'associer plusieurs exceptions à la suite. >>> def division(a,b): ... try: ... return a/b ... except ZeroDivisionError: ... return 'infini' ... except TypeError: ... return 'veuillez rentrer des nombres' Le bloc *else* est exécuté à la fin uniquement si il n'y a aucune erreur. .. index:: try..finally ------------ try..finally ------------ syntaxe :: try: bloc de code surveillé finally: code toujours exécuté (y compris si raise ou return dans le bloc surveillé). ------------------- quelques exceptions ------------------- - AttributeError - ImportError - IndentationError - IndexError - KeyError - MemoryError - SyntaxError - TypeError - ZeroDivisionError -------------------------------- Exercice -------------------------------- Compléter le script "tests_exercices.py" proposé dans l'archive.