Archives de catégorie : DebuterEnPython

OutillageTravauxPratiques

[wiki: Travaux Pratiques]

PageOutline

Dans ce TP, nous allons créer une calculatrice qui va prendre une expression et la calculer. L’objectif est d’utilisez « Spyder » et de développer un programme composé de multiples fichiers source. La calculatrice aura donc une fonction principale de calcul qui renverra le résultat de l’expression, qui s’utilisera ainsi :

$> python main.py


>>> 3 + 4 * 6 / 5
( ['=', '+', '*', '/'] [3.0, 4.0, 6.0, 5.0] )
8.4

>>> OFF


Le main

Créer un fichier main.py qui va récupérer l’expression tapée par l’utilisateur et l’afficher :

print()
ligne=input("calc> ")
print(" {:s} ".format(ligne))

Dans ce main, ajouter une boucle while qui récupère l’expression tapée tant que celle-ci est différente de « OFF »:

# -*- coding: utf-8 -*-


print()
ligne=input("calc> ")
while ligne!='OFF':
print(" {:s} ".format(ligne))
ligne=input("calc> ")


L’analyseur

Créer un fichier analyseur.py et y copier le code ci-dessous :

# -*- coding: utf-8 -*-


import re

parse_op = re.compile(r'[-+*/]')
parse_num = re.compile(r'[^-+*/]+')

def analyse(s):

opList = parse_op.findall(s)
numList = list(map(float, parse_num.findall(s)))

if len(opList) != len(numList):
opList.insert(0, '=')

return opList, numList


Retourner dans le fichier main, importer le module analyseur et appeler la fonction analyse avec l’expression fourni en paramétre. Afficher le résultat.

$> python main.py


>>> 3 + 4 * 6 / 5
3 + 4 * 6 / 5
(['=', '+', '*', '/'], [3.0, 4.0, 6.0, 5.0])

>>> OFF


Les opérateurs

Créer un sous répertoire « operateurs ».
Pour chaque opération (+,-,*,/), créer un fichier portant le nom de l’opération.
Pour chaque opération, écrire sa définition retournant le résultat.

.
| main.py
| operateurs
| | init.py
| | addition.py
| | division.py
| | multiplication.py
| | soustraction.py
| analyseur.py

Modifier le init.py afin de créer un dictionnaire mappant l’operateur avec sa fonction.

Fonction de calcul et affichage du résultat

  • créer un fichier nommé calculatrice.py
  • importer le package operateurs
  • importer la méthode analyse
  • créer une fonction calcul qui va prendre en paramètre une chaine de caractère
  • cette fonction va appeler la fonction analyse pour récupérer les opérateurs et les chiffres
  • pour chaque opérateur, appeler la fonction correspondante avec les bons arguments et récupérer le résultat
  • enfin cette fonction doit renvoyer le résultat global
  • modifier le main pour qu’il affiche le résultat de l’appel de cette fonction
#!comment


distribution

Créer un fichier setup.py avec le minimum d'information pour distribuer le projet:
{{{
from distutils.core import setup

setup(name = 'macalculatrice',
version = '1.0',
author = 'Jane Doe',
description = 'module de calculatrice',
packages = ['calculatrice', 'calculatrice.operateurs'],
)


Pour créer la version distribuable, lancer la commande python setup.py sdist.

Vous pouvez maintenant distribuer votre projet, après avoir récupéré l’archive, vous pouvez l’installer avec python setup.py install

Après installation, on peut directement appeler le module créer (se placer dans un autre répertoire sans les sources)

$> python
Python ...
Type "help", "copyright", "credits" or "license" for more information.


>>> from calculatrice.calculatrice import calcule

>>> calcule("3 + 4 * 6 / 5")
( ['=', '+', '*', '/'] [3.0, 4.0, 6.0, 5.0] )
8.4

>>> OFF


}}}


Attachments

LangageInstructionsControle

[wiki: Instructions de contrôle] [#license ©]

PageOutline

If, tests et conditions

#!python
if a > b:
  print('a>b')
elif a == b:
  print('a==b')
else:
  print('a<b')
>>> l = [ 0, 1, 2, 3 ]


>>> 2 in l, 4 in l
( True, False )


  • Condition non vérifiée :
  • False
  • Collection vide
  • Valeur numérique nulle
  • None
  • Condition vérifiée
  • True
  • Collection non vide
  • Valeur numérique non nulle
  • Opérateurs
  • and, or , not
  • <, <=, >, >=, ==, !=
  • in, is
#!comment
Comme en C++, les les structures conditionnelles acceptent toutes sortes d'expressions parce que le type bool n'existait pas à l'origine.

While

#!python
a = 0
max = 10
while a < max: 
  if cherche(a):
    print("chiffre",a)
    break ;
  a += 1 
else:
  print("pas de chiffre")

La clause else est éxecutée si while sort sur un échec de sa condition, et non sur un break.

#!comment
Pas de "do while".

For

  • in doit être suivi d’une séquence ou d’un itérateur, fournis explicitement ou retournés par une fonction.
#!python
for i in ['a', 'b', 'c']:
  print(i)
#!python
for i in range(10):
  print(i)
  • continue permet de passer directement à la valeur suivante.
#!python
for i in range(4):
  if i == 2:
      continue
  print(i)
#!html
<pre style="margin-left:50px;border: 1px solid palegoldenrod;padding:10px;background-color:lightyellow">
0
1
3
</pre>
  • break permet de sortir de la boucle.
#!python
for i in range(6):
  if i == 4:
      break
  print(i)
#!html
<pre style="margin-left:50px;border: 1px solid palegoldenrod;padding:10px;background-color:lightyellow">
0
1
2
3
</pre>
  • La clause else est éxecutée si for sort en fin d’itération, et non sur un break.
#!python
for i in range(4):
  if i == 2:
      continue
  print(i)
else:
  print('end')
#!html
<pre style="margin-left:50px;border: 1px solid palegoldenrod;padding:10px;background-color:lightyellow">
0
1
3
end
</pre>
  • Très déconseillé de modifier la séquence sur laquelle on itère.

Exercices

1. Écrire une boucle qui calcule la somme des dix premiers carrés (c’est à dire 1² + 2² + … + 9²).
1. Affichez à l’écran les quinze premiers multiples d’un nombre que vous choisirez.
1. Écrire une boucle qui affiche tous les nombres divisibles par 3 et par 5 dans un intervalle que vous choisirez.
1. Calculer la longueur d’une chaine de caractères (sans utiliser la fonction len()).
1. Écrire une boucle qui permet de compter le nombre de voyelles dans une chaine de caractères.
1. Créer un programme qui doit faire deviner au joueur un nombre entre 1 et 100 tiré aléatoirement (on pensera à utiliser le module random). Après chaque entrée, on indiquera au joueur si le nombre est plus grand ou petit. On pourra envisager d’ajouter un compteur de tentatives.

#!comment
from random import randint
rand_number = randint(1, 100)

Références

© David Chamont, Laboratoire Leprince-Ringuet (LLR) / IN2P3 / CNRS, Ecole polytechnique / Université Paris-Saclaybr
© Ce(tte) œuvre est mise à disposition selon les termes de la Licence Creative Commons Attribution – Partage dans les Mêmes Conditions 4.0 International [=#license]


Attachments

LangageAffectation

[wiki: Affectation] [#license ©]

PageOutline

Pour essayer les exemples, vous pouvez utiliser le Online Python Tutor.

Variables et valeurs

  • La première affectation à un nouvelle variable crée cette variable et la valeur correspondante.
  • Il faut visualiser variable et valeur comme deux entités différentes, la première désignant la seconde (plutôt que la contenant).
  • Les affectations suivantes font que la variable existante désigne une autre valeur.
  • Le type est attaché à la valeur (et non pas à la variable).
  • Les valeurs qui ne sont plus désignées sont récupérées par le ramasse-miette automatique.
  • PROGRAMMEURS C/C++, ATTENTION DANGER : il ne s’agit ni vraiment de variables ordinaires, ni vraiment de pointeurs…
#!comment


A REFAIRE : tous les diagrammes en mettant des nombres flottants.
(le partage automatique des valeurs entières est une exception
qui ne doit pas être mise en avant).

Pour les programmeurs C++, on peut voir les noms de python comme des pointeurs no typés (void *), mais qui sont automatiquement déréférencés quand on les utilise.
Ce sont les objets qui sont typés, et en réalité chaque objet est précédé en mémoire de deux entêtes :

  • son type
  • son compteur de références

Les objets qui ne sont plus pointés sont automatiquement récupérés par le ramasse-miette.On peut éliminés explicitement un nom avec le mot-réservé "del".


>>> a = 3
>>> a = 'hello'
>>> a = 1.23
#!html
<br clear=right>

Partage de valeurs

#!python
>>> a = 3
>>> b = a


>>> a = 'hello'

>>> a = b+2
>>> c = 3


#!html
<br clear=right>

Modification d’un élément de collection

#!python


>>> l1 = [2,3,4]
>>> l2 = l1

>>> l1[0] = 5


#!html
<br clear=right>

Forcer la duplication à l’aide d’une « tranche complète »

#!python


>>> l1 = [2,3,4]
>>> l2 = l1[:]

>>> l2[1] = 6


#!html
<br clear=right>

Copie superficielle et profonde

  • La duplication d’une séquence en faisant une tranche complète ([:]) ne fonctionne pas avec les associations (dictionnaires et ensembles). Une procédure valable pour toutes les collections, y compris les associations, consiste à utiliser la méthode copy() du module copy.
  • ATTENTION : cette façon de copier est « superficielle », c’est à dire qu’elle ne duplique que la structure de plus haut niveau, et ne duplique pas les éléments interne de la collection. Dans le cas de collections imbriquées, cela peut poser problème.
  • Pour dupliquer de façon récursive une collection et tous ses éléments, utilisez deepcopy().
#!python
>>> import copy
>>> l1 = [2,3,4]
>>> l2 = copy.copy(l1)
>>> l2[1] = 6
>>> print l1
[2,3,4]
>>> print l2
[2,6,4]


>>> import copy
>>> l1 = [1, [2,3,4], 5]
>>> l2 = copy.copy(l1)
>>> l2[1][1] = 6
>>> print l1
[1, [2,6,4], 5]
>>> print l2
[1, [2,6,4], 5]

>>> import copy
>>> l1 = [1, [2,3,4], 5]
>>> l2 = copy.deepcopy(l1)
>>> l2[1][1] = 6
>>> print l1
[1, [2,3,4], 5]
>>> print l2
[1, [2,6,4], 5]


#!html
<br clear=right>

Egalité et identité

#!python


>>> l1 = [2,3,4]
>>> l2 = l1
>>> l1==l2
True
>>> l1 is l2
True


#!html
<br clear=right>
#!python


>>> l1 = [2,3,4]
>>> l2 = [2,3,4]
>>> l1==l2
True
>>> l1 is l2
False


#!html
<br clear=right>
#!python


>>> x = 42.5
>>> y = 42.5
>>> x==y
True
>>> x is y
False


#!html
<br clear=right>

Dans le cas précis des int, pour éviter de recréer de multiples instances des mêmes petits entiers, Python réutilise une seule et même valeur quand c’est possible.

#!python


>>> x = 42
>>> y = 42
>>> x==y
True
>>> x is y
True


ATTENTION DANGER : is est peut-être beaucoup plus rapide que == dans certaines circonstances, mais c’est un faux ami qui expose des mécanismes interne de Python ; à utiliser avec précaution pour les collections, quand les performances l’exige ; à éviter pour les valeurs numériques scalaires.

#!html
<br clear=right>

Passage d’arguments

Suite à un appel de fonction, les paramètres désignent les mêmes valeurs que les variables données en argument.
Modifier un paramètre n’affecte pas la variable extérieure.
Modifier un élément de ce paramètre, si il désigne uen collection modifiable, affectera la variable extérieure qui désigne la même collection.

#!python


>>> def changer(a,b):
... a = 2
... b[0] = 'hello'
...
>>> x = 1
>>> y = [1,2]
>>> changer(x,y) # a,b = x,y
>>> x,y
(1,['hello',2])


#!html
<br clear=right>

Affectation dans une fonction

ATTENTION DANGER : dans une fonction, toute affectation à une variable qui n’est pas un paramètre, entraine la création d’une variable locale à la fonction, sauf si il s’agit d’un élément de collection modifiable.

#!python
>>> x = 88
>>> y = [ 1, 2 ]
>>> def func():
...   x = 99
...   y[0] = 0
...
>>> func()
>>> x, y
   ( 88, [0,2] )
#!html
<br clear=right>

Résumé

  • Les types sont attachés aux valeurs, pas aux variables.
  • Chaque valeur est rendue au système quand elle n’est plus désignée par aucune variable.
  • La modification d’un élément de collection affecte toutes les variables désignant cette collection.
  • Le passage des arguments d’une fonction se fait par affectation à des variables locales.
  • Les affectations au sein des fonctions créent des variables locales.
#!comment
A la différence de C++, qui distingue


  • variables ordinaires, références, pointeurs.
  • passage d'arguments par valeur, référence, pointeur.

#!html
<br clear=right>

Quiz

1. Quelle est la valeur finale retournée par a ?

#!python
>>> a = "hello"
>>> b = a
>>> b = "world"
>>> a

1. Quelle est la valeur finale retournée par a ?

#!python
>>> a = [ "hello" ]
>>> b = a
>>> b[0] = "world"
>>> a

1. Quelle est la valeur finale retournée par a ?

#!python
>>> a = [ "hello" ]
>>> b = a[:]
>>> b[0] = "world"
>>> a

1. Quelle est la valeur finale retournée par a ?

#!python
>>> def f(x):
...   x = "world"
...
>>> a = "hello"
>>> f(a)
>>> a

1. Quelle est la valeur finale retournée par a ?

#!python
>>> def f(x):
...   x[0] = "world"
...
>>> a = [ "hello" ]
>>> f(a)
>>> a

© David Chamont, Laboratoire Leprince-Ringuet (LLR) / IN2P3 / CNRS, Ecole polytechnique / Université Paris-Saclaybr
© Ce(tte) œuvre est mise à disposition selon les termes de la Licence Creative Commons Attribution – Partage dans les Mêmes Conditions 4.0 International [=#license]


Attachments

LangageTypesPredefinis

[wiki: Types prédéfinis] [#license ©]

PageOutline

Vue d’ensemble

  • Nombres : int, float, complex.
  • Collections
  • Séquences non modifiables
  • str : 'hello' ou "hello"
  • tuple : 'a', 'b', 'c'
  • Séquences modifiables
  • list : [ 'a', 'b', 'c' ]
  • Associations modifiables
  • dict : { 'a' : 'val', 3 : 'x', 'key' : 124 }
  • set : { 'a', 3, 'key' }
  • Associations non modifiables
  • frozenset : { 'a', 3, 'key' }
  • Divers
  • bool
  • !NoneType : None
  • type

Entiers

  • int
  • Peut prendre des valeurs illimitées, et se charge d’optimiser la représentation interne des entiers.
  • La fonction int() permet de transformer explicitement un texte en nombre. En cas d’impossibilité, l’exception !ValueError est émise.
  • La fonction str() transforme un entier en chaîne de caractères.

Réels et complexes

  • float
  • équivalent d’un double du C.
  • ces nombres s’écrivent avec un « . » et/ou un exposant « e » ou « E » : 1.23, 3.14e-10, 4E210, 4.0e+210
  • complex
  • équivalent de deux floats
  • s’écrit avec un « j » ou « J » : 3+4j
  • la fonction str() transforme un float ou un complex en chaîne de caractères. les fonctions float() et complex() transforment une chaîne de caractère en float ou complex.

Opérations numériques

  • Un opérateur puissance :
**
  • Quelques opérateurs spécifiques aux entiers :
& | ^ ~ << >>
  • Deux formes de division
  • / : division classique qui retourne un nombre flottant, quel que soit ses arguments.
  • // : quotient entier qui retourne un flottant en cas d’arguments flottants, un entier en cas d’arguments entiers.
>>> 2/3
0.6666…
>>> 2//3
0
>>> 2./3.
0.6666…
>>> 2.//3.
0.0
>>> 6/2
3.0
>>> 6//2
3
>>> 6./2.
3.0
>>> 6.//2.
3.0

Séquences (str, tuple, list)

  • Nombre d’éléments par len(<sequence>)
  • Accès aux éléments par [<indice>]
  • Les indices négatifs permettent de parcourir les éléments en partant de la fin
  • Le premier élément a l’indice 0 ou -len()
  • Le dernier élément a l’indice len()-1 ou -1
  • On peut extraire une tranche en donnant un indice de départ, un indice de fin (exclus), et éventuellement un pas, séparé par des « : »
  • Les mauvais indices induisent une exception IndexError
>>> li = 1, 2, 3, 4
>>> len(li)
4
>>> li[0]
1
>>> li[-1]
4
>>> li[0:2]
(1, 2)
>>> li[:2]
(1, 2)
>>> li[1:]
(2, 3, 4)
>>> li[::2]
(1, 3)
>>> li[3:0:-2]
(4,2)

Modification des listes

  • Modifier un élément ou une tranche
  • l[i] = x
  • l[i:j:k] = t
  • Supprimer un éléments ou une tranche
  • del l[i]
  • del l[i:j:k]
  • Ajouter un élément ou une séquence
  • l.append(x)
  • l.insert(i,x)
  • l.extend(t)
  • Diverses méthodes : reverse(), sort()…
>>> li = [ 1, 2, 3, 4 ]
>>> li[0:3:2] = [ -1,-2]
>>> li
[ -1, 2, -2, 4 ]
>>> del li[:2]
>>> li
[ -2, 4 ]
>>> li.insert(1,None)
>>> li
[ -2, None, 4 ]
>>> li.extend( [ 1, 2 ] )
>>> li
[ -2, None, 4, 1, 2 ]
>>> li.sort()
>>> li.reverse()
>>> li
[ 4, 2, 1, -2, None ]

Tuples

  • 'a', 'b', 'c' ou ('a', 'b', 'c') (ce sont les virgules qui déclenchent la création du tuple, pas les parenthèses).
  • Non modifiables et optimisés en conséquence.
  • Souvent utilisés implicitement, notamment dans les instructions qui reposent sur un ensemble de valeurs séparées par des virgules.
  • ATTENTION: les parenthèses sont aussi utilisées pour grouper des éléments dans une expression. Pour éviter certaines ambiguités, quand un tuple ne contient qu’un seul élément, on laisse une virgule avant la parenthèse fermante. Le cas le plus dangereux est celui d’un tuple de chaines de caractères, car si il y a une seul chaine et qu’on oublie la virgule, la chaine est interprétée comme une séquence de n caractères.
>>> l = ['t','o','t','o']
>>> tpl = tuple(l)
>>> tpl[0]
't'
>>> s = 'toto'
>>> tpl = tuple(s)
>>> tpl[0]
't'
>>> tpl = ( 'toto', 'tutu' )
>>> tpl[0]
'toto'
>>> tpl = 'toto', 'tutu'
>>> tpl[0]
'toto'
>>> tpl = ('toto')
>>> tpl[0]
't'
>>> tpl = ('toto',)
>>> tpl[0]
'toto'
>>> tpl = 'toto',
>>> tpl[0]
'toto'

Chaines de caractères

Type str. Les caractères sont unicode (par défaut en UTF8).

Définition d’une chaîne :

  • Quatres sortes de littéraux (ordinaire=unicode, brute, multi-ligne, octets=ascii)
  • Pas de différence entre ‘ et « 
  • Utilisation habituelle du \ pour éliminer le comportement spécial d’une fin de ligne, d’une quote ou du backslash lui-même.
>>> s1 = "chaine unicode"
>>> s2 = r"chaine brute"
>>> s3 = """
chaine
multi-ligne
"""
>>> s4 = b"chaine d'octets"

Opérateurs

  • + et *
  • Accès aux lettres par [], mais interdiction de la modifier : toutes les méthodes ou fonctions applicables aux chaines de caractères retournent une copie modifiée de l’originale.

Quelques fonctions et méthodes

  • len() : renvoie la taille d’une chaîne,
  • str.find() : recherche une sous-chaîne dans la chaîne,
  • str.rstrip() : enlève les espaces de fin,
  • str.replace() : remplace une chaîne par une autre,
  • str.split() : découpe une chaîne en liste,
  • str.join() : concatène une liste en chaîne,
  • str.isdigit() : renvoie True si la chaîne contient que des nombres, False sinon.
  • str.format() : formatage de données.

L’utilisation de méthodes, notamment sur les littéraux, peut surprendre au premier abord :

>>> elements = 'A/B/C'.split('/')
>>> print('|'.join(elements))
A|B|C

On notera également que l’ancien opérateur de formattage %, sujet à de nombreux problèmes, n’est plus recommandé. On lui préfèrera la méthode str.format(), beaucoup plus complète, tout en restant familière dans les cas simples :

>>>'{0:03.2f} {2:d} {1:f}'.format(1/3,2/3,1)
'0.33 1 0.666667'
#!comment
Rappelons que Python est un langage au typage fort : il ne considère donc pas '1' comme un nombre
On transforme une chaîne en nombre avec les fonctions int(), long(), float(), complex().

On peut donner plusieurs chaines à la suite, séparées par des espaces, et l’interpréteur procédera à une concaténation automatique. A condition de mettre des parenthèses, on peut même le faire sur plusieurs lignes :

>>> s = '1' '2' '3'
>>> s
'123'
>>> s = (
... '1'
... '2'
... '3'
... )
>>> s
'123'

ATTENTION : cette propriété n’est pas très recommandable, sauf cas très particuliers, mais il est utile de la connaître pour comprendre certains dysfonctionnements. Par exemple, si on insère des virgules par erreur ou si on en oublie :

>>> s = (
... '1',
... '2'
... '3'
... )
>>> s
('1', '23')

Dictionnaires

  • On peut utiliser comme clé, entre [], tout objet non modifiable.
  • Lorsqu’on modifie un élément dont la clé n’existe pas, elle est crée.
  • Lorsqu’on lit un élément dont la clé n’existe pas, une exception !NameError est levée.
  • On peut mélanger tous les types de clés et de valeurs dans un même dictionnaire.
>>> d = { 8: 'val', 3.2: 'x', 'key': 124 }
>>> d[3.2]
'x'
>>> d.keys()
[ 8, 3.2, 'key' ]
>>> d.values()
[ 'val', 'x', 124 ]
>>> d[(1,)] = None
>>> del d[3.2]
>>> d
{ 8: 'val', 'key': 124, (1,): None }
>>> d2 = d.copy()
>>> d.clear()
>>> d2
{ 8: 'val', 'key': 124, (1,): None }
>>> d
{}
#!comment
les dictionnaires ne sont pas des ensembles ordonnés, c’est à dire que l’on ne peut prédire à quel endroit s’ajoutera une paire
pas de slices ?

Quelques autres

  • set et frozenset : des ensembles, dotés des opérateurs |&-^ et des méthodes issubset() et issuperset().
  • bool : prend la valeur True ou False.
  • !NoneType : le type de None.
  • type : le type de tous les objets types.
>>> type(True)
<class 'bool'>


>>> type(None)
<class 'NoneType'>

>>> type(type(True))
<class 'type'>

>>> type(type(None))
<class 'type'>


#!comment
Autres types :
fonctions
modules

Exercices

Essayez et modifiez les exemples ci_dessus, soit avec le Online Python Tutor, soit avec l’interpréteur IPython fourni avec Anaconda. »

Références

© David Chamont, Laboratoire Leprince-Ringuet (LLR) / IN2P3 / CNRS, Ecole polytechnique / Université Paris-Saclaybr
© Ce(tte) œuvre est mise à disposition selon les termes de la Licence Creative Commons Attribution – Partage dans les Mêmes Conditions 4.0 International [=#license]


Attachments

LangageIntroduction

[wiki: Introduction]

PageOutline

#!comment


A ce stade : on essaie tout le prompt.
Ensuite : on passe en fichiers.

A revoir :
*) pour les débutants, faire l'impasse sur la réutilisation des objets entiers et le "is" (peut-être classer "is" dans les pièges).
*) refaire les démos en "animations"
*) parler de "shallow copy" et "deep copy".


Historique

  • Fin des années 80 : au sein du Centrum voor Wiskunde en Informatica (Pays-Bas), Guido van Rossum concoit un langage de script inspiré d’ABC, Modula-3, C, Unix.
  • 1991 : Python 0.9.0 est posté sur le forum alt.sources.
  • 2001 : Python 2.1, première version de la Python Software Foundation.
  • 2008 : Python 3.0, non compatible avec les précédentes.

Fiche d’identité

  • Python est un langage
  • Semi-interprété : interprété, mais compilé au vol dans un langage propre à chaque interpréteur (CPython, Jython, !IronPython).
  • Multi-paradigmes : impératif, orienté objets (classes et héritage), fonctionnel…
  • Typage :
  • dynamique : le type est attaché aux objets (pas aux variables ou références vers ces objets), il est présent et interrogeable à l’éxécution (introspection).
  • fort : refus d’additionner des pommes et des poires, ni de transformer implicitement un type dans un autre.
  • « canard » : si je vois un animal qui vole comme un canard, cancane comme un canard, et nage comme un canard, alors j’appelle cet oiseau un canard => une fonction peut utiliser n’importe quel objet, du moment qu’il offre l’interface attendue (un peu comme les templates C++).
  • Gestion automatique de la mémoire : les variables sont des références vers les objets, et les copies ne copient en général que la référence, pas l’objet. Les objets qui ne sont plus référencés sont automatiquement récupérés par le ramasse-miette.
  • Utilisé pour
  • Scripts d’administration de système.
  • Sites webs (celui-ci ! Django, TurboGears, Zope, Plone, …).
  • Applications bureautiques.
  • Calcul scientifique (NumPy, SciPy, Sage), les parties sensible étant optimisées en C.

Mise en page

  • Une instruction par ligne.
  • On peut poursuivre sur plusieurs lignes avec « \ » ou parenthèses.
  • On peut mettre plusieurs instructions par ligne séparées par des « ; » (non recommandé).
  • Les blocs d’instructions sont indentés.
  • Commentaires par « # ».
if a > 1 and b > 5 \
        and c < 3:
    print(1)


if (a > 1 and b > 5
and c < 3):
print(1)

a = 1
if a > 2:
b = a + 1
print(b)
print(a)

# commentaire
print(1) # un autre commentaire


Variables

  • Identifiants
  • lettres, chiffres et « _ » .
  • interdit d’utiliser les mot-clés (ou mots réservés).
  • dangereux de redéfinir les built-in.
  • * : par convention, noms définis par le système.
  • Affectation par « = »
  • Comparaison par « == »
  • On peut voir le contenu d’une variable…
  • en donnant son nom à l’interpréteur python ;
  • ou en utilisant la fonction print().
  • Affectations multiples
prompt> a, b, c = 1, 2, 'hello'
prompt> x, y = y, x
#!comment


Les caractères non-ascii sont autorisés depuis Python3… à éviter !!


Types de base

  • Nombres : 1234, 3.1415, 999999999999999999999999999, 3+4j.
  • Chaines de caractères : 'spam', "guido's".
  • Listes : [1, [2, 'three'], 4].
  • Dictionnaires : {'a': 'val', 3: 'x', 'key': 124}.
  • Tuples : (1, 'spam', 4, 'U' ).
  • Fichiers : myfile = open('eggs','r').
  • Autres : Sets, types, None, Booleans.
#!comment


on peut mélanger des torchons et des serviettes
on peut imbriquer les collections
Objet None


Instructions de contrôle de flux

#!python


if a > b:
print('a>b')
elif a == b:
print('a==b')
else:
print('a<b')


#!python


while a < max:
print(a)
a += 1


#!python


for i in ['a', 'b', 'c']:
print(i)


#!python


for i in range(10):
print(i)


#!python


for i in range(4):
if i == 2:
continue
print(i)


#!html
<pre style="margin-left:50px;border: 1px solid lightgoldenrodyellow;padding:10px;background-color:lightyellow">
0
1
3
</pre>
#!python


for i in range(6):
if i == 4:
break
print(i)


#!html
<pre style="margin-left:50px;border: 1px solid lightgoldenrodyellow;padding:10px;background-color:lightyellow">
0
1
2
3
</pre>
#!comment


Expression : booléen ou nombre, considéré comme True si différent de 0.
For attend un itérateur
Très déconseillé de modifier la séquence sur laquelle on itère
En python 2, on préfèrera xrange plutôt que range.
Pas de switch.


Fonctions

  • Définition :

1. « def », suivi du nom de la fonction, suivi des arguments entre parenthèses (sans types), suivi de « : »
1. bloc indenté d’instructions

  • Retour :
  • si « return » est suivi d’une liste de valeurs séparées par des virgules, elles sont empaquetées en tuple.
  • en absence de « return », la fonction retourne « None ».
  • Appel de fonction : les valeurs données entre parenthèses sont affectées aux arguments, dans l’ordre.
#!python


def divs(x,y):
'Essaie / et //.'
res1 = x/y
res2 = x//y
return res1, res2

divs(2.,3.)


#!html
<pre style="margin-left:50px;border: 1px solid lightgoldenrodyellow;padding:10px;background-color:lightyellow">
(0.6666666666666666, 0.0)
</pre>

Opérateurs

  • Opérateurs
& | ^ ~ << >>


= != < > <= >

+ - * ** / // %


  • Délimiteurs
( ) [ ] { } 
    , : . ; @
    = += -= *= /= //= %= &= |= ^= >>= <<= **=
#!comment


On notera :
** : puissance
/ et //
% avec une string à gauche : formatage


Bibliothèque standard

import random
rand_number = random.randint(1, 100)

Mot-clés

pass
None False True
if elif else while for continue break
is in and or not
def return lambda yield
del global
class
import as from
assert try raise except finally with
nonlocal

Installation des outils

Pour l’environnement Windows, nous vous proposons d’installer les dernières versions de la distribution ActivePython, à la fois pour Python 2 et Python 3, afin de pouvoir expérimenter les deux versions. Une fois ces distributions installées, ce qui demandera sans doute une intervention du formateur pour passer en mode administrateur, vous pourrez utiliser deux programmes disponibles dans le menu « démarrer / tous les programmes » :

  • !ActiveState !ActivePython … / Python Interactive Shell : pour executer des commandes simples.
  • !ActiveState !ActivePython … / IDLE : pour executer des commandes simples et des fichiers.

Trucs et astuces pour grands débutants

  • N’oubliez pas le ‘:’ à la fin de vos if/while/for.
  • Commencer vos instructions de plu shaut niveau sur la colonne 1.
  • Avec l’interpréteur les lignes blanches comptent ! (elles marquent la fin d’un bloc d’instructions, alors que dans un fichier elles sont ignorées).
  • Ne mélangez pas tabulations et espaces pour votre indentation, et soyez très attentifs à ce que fait votre éditeur « intelligent » en la matière. Un texte qui semble aligné peut ne pas l’être du pont de vue de Python, ou dans un autre éditeur qui gère différemment les tabulations.
  • Ne faites pas du C
  • inutile de mettre vos conditions entre parenthèses
  • inutile de terminer les lignes par des ‘;’
  • ne faites pas d’assignation dans les conditions
  • ne mettez pas de {} autour de vos blocs d’instructions.

Attachments

LangageDocumentation

[wiki: Documentation]

PageOutline

Comment insérer ou récupérer de la documentation sur votre code et sur les éléments intégrés du langage ?

Commentaires

Sur chaque ligne, l’interpréteur ignore le caractère ‘#’ et tout ce qui le suit, à condition qu’il ne soit pas inclus dans une chaîne de caractères littérale.

>>> # commentaire


>>> print(1) # un autre commentaire
1

>>> texte = '1 # non commentaire'
>>> print(texte)
1 # non commentaire


Fonction dir()

  • La fonction intégrée dir() permet de lister les attributs de tout objet, variables et fonctions.
  • Cela s’applique aux modules.
  • Cela s’applique aux variables littérales des types prédéfinis, y compris les collections.
  • On peut donner le nom d’un type
>>> import sys


>>> dir(sys)
['displayhook', 'doc', 'excepthook', 'name', 'package',
'stderr', 'stdin', 'stdout', '_clear_type_cache', '_current_frames',
'_getframe', '_mercurial', 'api_version',
'argv', 'builtin_module_names', 'byteorder', 'call_tracing', 'callstats',
'copyright', 'displayhook', 'dllhandle', 'dont_write_bytecode', 'exc_clear',
'exc_info', 'exc_traceback', 'exc_type', 'exc_value', 'excepthook', 'exec_prefix',
'executable', 'exit', 'flags', 'float_info', 'float_repr_style', 'getcheckinterval',
'getdefaultencoding', 'getfilesystemencoding', 'getprofile', 'getrecursionlimit',
'getrefcount', 'getsizeof', 'gettrace', 'getwindowsversion', 'hexversion',
'long_info', 'maxint', 'maxsize', 'maxunicode', 'meta_path', 'modules',
'path', 'path_hooks', 'path_importer_cache', 'platform', 'prefix',
'py3kwarning', 'setcheckinterval', 'setprofile', 'setrecursionlimit',
'settrace', 'stderr', 'stdin', 'stdout', 'subversion', 'version',
'version_info', 'warnoptions', 'winver']

>>> dir(3)
['abs', 'add', 'and', 'class', 'cmp', 'coerce',
'delattr', 'div', 'divmod', 'doc', 'float', 'floordiv',
'format', 'getattribute', 'getnewargs', 'hash', 'hex',
'index', 'init', 'int', 'invert', 'long', 'lshift',
'mod', 'mul', 'neg', 'new', 'nonzero', 'oct', 'or',
'pos', 'pow', 'radd', 'rand', 'rdiv', 'rdivmod',
'reduce', 'reduce_ex', 'repr', 'rfloordiv', 'rlshift',
'rmod', 'rmul', 'ror', 'rpow', 'rrshift', 'rshift',
'rsub', 'rtruediv', 'rxor', 'setattr', 'sizeof', 'str',
'sub', 'subclasshook', 'truediv', 'trunc', 'xor', 'bit_length',
'conjugate', 'denominator', 'imag', 'numerator', 'real']

>>> dir([])
['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']

>>> dir([]) == dir(list)
True

>>>dir(str)
['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', '_formatter_parser',
'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']


Chaines de documentation (docstrings)

  • Au delà des commentaires, on peut doter un objet d’une documentation courte, consultable à l’exécution.
  • Syntaxiquement, on insère une chaîne de caractère en haut d’un module, d’une fonction ou d’une classe, avant toute instruction exécutable.
  • Une telle chaîne est automatiquement stockée dans l’attribut doc de l’objet.
  • Cette chaîne peut être multi-lignes, comme dans ce fichier vecteurs3d.py :
#!python
"""
Le module vecteurs3d permet de manipuler des
tuples de trois éléments.
"""


def norme(v):
'Calcul de la norme d'un tuple de trois coordonnées.'
x2 = v[0]**2
y2 = v[1]**2
z2 = v[2]**2
return (x2+y2+z2)**(1/2)

def produit(v1,v2):
'Multiplication terme à terme de deux tuples.'
x = v1[0]*v2[0]
y = v1[1]*v2[1]
z = v1[2]*v2[2]
return x,y,z


  • Il n’y a pas de convention répandue sur la façon d’écrire vos chaines de documentation.
  • Les modules et fonction intégrées sont dotées de chaines de documentation :
#!python


>>> import sys
>>> print sys.doc
This module provides access to some objects used or maintained by the
interpreter and to functions that interact strongly with the interpreter.

Dynamic objects:

argv -- command line arguments; argv[0] is the script pathname if known
path -- module search path; path[0] is the script directory, else ''
modules -- dictionary of loaded modules

displayhook -- called to show results in an interactive session
excepthook -- called to handle any uncaught exception other than SystemExit
To customize printing in an interactive session or to install a custom
top-level exception handler, assign other functions to replace these.

exitfunc -- if sys.exitfunc exists, this routine is called when Python exits
Assigning to sys.exitfunc is deprecated; use the atexit module instead.

stdin -- standard input file object; used by raw_input() and input()
stdout -- standard output file object; used by the print statement
stderr -- standard error object; used for error messages
By assigning other file objects (or objects that behave like files)
to these, it is possible to redirect all of the interpreter's I/O.

last_type -- type of last uncaught exception
last_value -- value of last uncaught exception
last_traceback -- traceback of last uncaught exception
These three are only available in an interactive session after a
traceback has been printed.

exc_type -- type of exception currently being handled
exc_value -- value of exception currently being handled
exc_traceback -- traceback of exception currently being handled
The function exc_info() should be used instead of these three,
because it is thread-safe.

Static objects:

float_info -- a dict with information about the float inplementation.
long_info -- a struct sequence with information about the long implementation.
maxint -- the largest supported integer (the smallest is -maxint-1)
maxsize -- the largest supported length of containers.
maxunicode -- the largest supported character
builtin_module_names -- tuple of module names built into this interpreter
version -- the version of this interpreter as a string
version_info -- version information as a named tuple
hexversion -- version information encoded as a single integer
copyright -- copyright notice pertaining to this interpreter
platform -- platform identifier
executable -- absolute path of the executable binary of the Python interpreter
prefix -- prefix used to find the Python library
exec_prefix -- prefix used to find the machine-specific Python library
float_repr_style -- string indicating the style of repr() output for floats
dllhandle -- [Windows only] integer handle of the Python DLL
winver -- [Windows only] version number of the Python DLL
stdin -- the original stdin; don't touch!
stdout -- the original stdout; don't touch!
stderr -- the original stderr; don't touch!
displayhook -- the original displayhook; don't touch!
excepthook -- the original excepthook; don't touch!

Functions:

displayhook() -- print an object to the screen, and save it in builtin._
excepthook() -- print an exception and its traceback to sys.stderr
exc_info() -- return thread-safe information about the current exception
exc_clear() -- clear the exception state for the current thread
exit() -- exit the interpreter by raising SystemExit
getdlopenflags() -- returns flags to be used for dlopen() calls
getprofile() -- get the global profiling function
getrefcount() -- return the reference count for an object (plus one :-)
getrecursionlimit() -- return the max recursion depth for the interpreter
getsizeof() -- return the size of an object in bytes
gettrace() -- get the global debug tracing function
setcheckinterval() -- control how often the interpreter checks for events
setdlopenflags() -- set the flags to be used for dlopen() calls
setprofile() -- set the global profiling function
setrecursionlimit() -- set the max recursion depth for the interpreter
settrace() -- set the global debug tracing function

>>> print sys.getrefcount.doc
getrefcount(object) -> integer

Return the reference count of object. The count returned is generally
one higher than you might expect, because it includes the (temporary)
reference as an argument to getrefcount().


  • Ansi que les fonctions intégrées :
#!python


>>> print int.doc
int(x=0) -> int or long
int(x, base=10) -> int or long

Convert a number or string to an integer, or return 0 if no arguments
are given. If x is floating point, the conversion truncates towards zero.
If x is outside the integer range, the function returns a long instead.

If x is not a number or if base is given, then x must be a string or
Unicode object representing an integer literal in the given base. The
literal can be preceded by '+' or '-' and be surrounded by whitespace.
The base defaults to 10. Valid bases are 0 and 2-36. Base 0 means to
interpret the base from the string as an integer literal.
>>> int('0b100', base=0)
4


!PyDoc : fonction help()

La fonction help() est capable d’inspecter toutes les informations internes d’un module, d’une fonction ou d’une classe, y compris les chaine de documentation, afin de construire une documentation consultable en ligne avec une mise en page améliorée. Par exemple, en reprenant le fichier vecteurs3d.py décrit plus haut :

#!python


>>> import vecteurs3d
>>> help(vecteurs3d)
NAME
vecteurs3d

DESCRIPTION
Le module vecteurs3d permet de manipuler des
tuples de trois éléments.

FUNCTIONS
norme(v)
Calcul de la norme d'un tuple de trois coordonnées.

produit(v1, v2)
Multiplication terme à terme de deux tuples.


Cela fonctionne avec tous les éléments intégrés du langage et de la bibliothèque standard :

#!python


>>> help(str.replace)
Help on method_descriptor:

replace(...)
S.replace(old, new[, count]) -> string

Return a copy of string S with all occurrences of substring
old replaced by new. If the optional argument count is
given, only the first count occurrences are replaced.


!PyDoc : rapport HTML

!PyDoc est également capable de générer des pages HTML. Cela a peu d’intérêt pour les eléments prédéfinis, qui sont mieux décrits dans le site web officiel. Par contre, c’est un moyen simple de générer des pages HTML à partir de vos propres fichiers. Cette opération ne s’effectue pas au sein de l’interpréteur, mais à partir d’un programme spécial :

1. Ajoutez vos répertoires de développement à la variable PYTHONPATH
1. Lancez !PyDoc (en windows : pythonw c:\Python27\Tools\scripts\pydocgui.pyw).
1. Nommez le module qui vous intéresse et lancez la recherche.
1. Sélectionner le module… cela ouvrira une fenêtre dans votre navigateur.

Sphinx

Site web officiel

Pour les eléments standards, rien n’égale la documentation web officielle, qui comprend entre autres :

Le tout en variante 2 comme en variante 3.

LangageModules

[wiki: Modules] [#license ©]

PageOutline

Définition d’un module

  • Tout programme python peut-être découpé en plusieurs fichiers.
  • L’importation d’un fichier occasionne la création d’un objet de type module, qui recevra toutes les variables et fonctions définies au sein du fichier.
  • Instructions ou fonction prédéfinies permettant d’importer un fichier :
  • import (récupération d’un fichier complet)
  • from (récupération de quelques éléments)
  • reload (force le rechargement)

Premier import

Effet de la première instruction import mod d’un programme :
1. Recherche du fichier mod.py dans les répertoires de la liste sys.path :
1. répertoire courant
1. répertoires de PYTHONPATH
1. répertoires standards
1. Compilation, si mod.pyc n’est pas à jour.
1. Exécution de mod.pyc, en enregistrant variables et fonctions dans le module ainsi créé (attributs du module).

Pour faire en sorte que le fichier soit d’abord recherché dans le répertoire ou se trouve la commande d’importation (import relatif), on utilisera from . import mod.

Effet de l’instruction « import module1 »

  • On accède aux attributs du module avec l’opérateur « . »
  • module1.py :
#!python
prompt = '%'
def printer(x):
  print(prompt,x)
  • ligne de commandes :
>>> import module1


>>> module1.printer('Hello')
% Hello


  • variante relative : from . import module1

Effet de l’instruction « import module1 as m1 »

  • module1.py :
#!python
prompt = '%'
def printer(x):
  print(prompt,x)
  • ligne de commandes :
>>> import module1 as m1


>>> m1.printer('Hello')
% Hello


  • variante relative : from . import module1 as m1

Effet de l’instruction « from module1 import printer »

  • module1.py :
#!python
prompt = '%'
def printer(x):
  print(prompt,x)
  • ligne de commandes :
>>> from module1 import printer


>>> printer('Hello')
% Hello


  • variante relative : from .module1 import printer
#!html
<br clear=right>

Effet de l’instruction « from module1 import printer as pr »

  • module1.py :
#!python
prompt = '%'
def printer(x):
  print(prompt,x)
  • ligne de commandes :
>>> from module1 import printer as pr


>>> pr('Hello')
% Hello


  • variante relative : from .module1 import printer as pr

Effet de l’instruction « from module1 import * »

  • module1.py :
#!python
prompt = '%'
def printer(x):
  print(prompt,x)
  • ligne de commandes :
>>> from module1 import *


>>> printer('Hello')
% Hello


  • variante relative : from .module1 import *

Import et from sont des instructions d’affectation

  • Elles peuvent être insérées n’importe où dans le code.
  • Elles sont interprétées à l’éxécution.
  • Les variables importées, si elles existaient auparavant, sont redirigées sur les nouvelles valeurs ou objets créés en mémoire (et on perd les anciennes valeurs).
  • Il n’y a aucun contrôle d’accès, pas d’attributs privés ou publics. Tout élément d’un module peut être lu et modifié, à condition de disposer d’une variable qui le désigne. sys.path peut-être redéfini à tout moment, affectant les futures instructions d’importation.

Restreindre « from * »

Deux moyens permettent de limiter les « dégâts » d’un from module import * :
1. préfixer une variable par « _ » pour que son nom ne soit pas importé.

#!python
x = 1
y = 2
_z = 3

1. lister explicitement les noms à importer à l’aide de la liste all

#!python
x = 1
y = 2
z = 3
all = [ 'x', 'y' ]

Quizz

  • module1.py :
#!python
prompt = '%'
def printer(x):
  print(prompt,x)

1. « % Hello » ou « > Hello » ?

>>> m = 2


>>> import module1 as m

>>> m.prompt = '>'

>>> m.printer('Hello')


#!comment
A la différence de C++, qui distingue
variables ordinaires, références, pointeurs.
passage d'arguments par valeur, référence, pointeur.

1. « # Hello » ou « % Hello » ou « > Hello » ?

>>> prompt = '#'


>>> from module1 import *

>>> prompt = '>'

>>> printer('Hello !')


Fonction prédéfinie reload()

Pour des raisons d’efficacité, lorsqu’on importe plusieurs fois le même module, seule la première instruction à de l’effet.
Par contre, si on a modifié le code d’un module, on veut pouvoir forcer sa ré-importation.
C’est le but de la fonction reload() :

  • N’est autorisé que pour un module déjà importé.
  • Ré-éxécute les instructions du fichier, et replace les nouveaux attributs au sein du module existant.
  • Le code client qui utilise le nom de module verra les nouveaux objets.
  • ATTENTION : le code client qui utilise des variables créées par from verra les anciens objets.
  • ATTENTION : reload() n’est pas transitif.
  • module1.py :
#!python
prompt = '%'
def printer(x):
  print(prompt,x)
  • ligne de commandes :
>>> import module1 as m1


>>> m1.prompt = '>'

>>> m2 = m1

>>> from module1 import *

>>> m1.prompt, m2.prompt, prompt
( '>' , '>' , '>' )

>>> reload(m1)

>>> m1.prompt, m2.prompt, prompt
( '%' , '%' , '>' )


#!comment
Mais reload n'est autorisé que sur un module déjà importé, travaille au sein de ce module, et surtout n'est pas transitif.
Morale, sur un gros programme plein de modules : renoncer au from, renoncer à l'interpréteur, renoncer à reload.

Résumé

  • Lors du premier appel à import ou from, le fichier correspondant est intégralement compilé, éxécuté et chargé en mémoire.
  • import crée une variable désignant l’ensemble du module.
  • from crée des variables vers les éléments du module.
  • reload() force la ré-éxécution des instructions du fichier.

Quelques pièges, truc et astuces

  • Attention à l’instruction from, qui peut écraser des variables déjà utilisées avec celles de même nom issues du module.
  • Attention à l’usage simultané de from et de reload.
  • Parce qu’un nom de fichier python est appelé à être utilisé comme module de même nom, il faut suivre les règles s’appliquant aux noms de variables. Evitez print.py !
#!comment
Morale : l'utilisation directe de l'interpréteur, pour débugguer, ne fonctionne que sur les petits programmes ; pour des gros programmes, avec modules, mieux vaut revenir à un modèle de développement ou pour tester on relance à chaque fois le programme from scratch ; reload est trop dangereux.
#!html
<br clear=right>

Quizz

3. Quels affichages ?

#!python
# fichier small.py
x = 1
y = [ 2, 3 ]
>>> from small import x, y


>>> x = 4

>>> y[0] = 5

>>> import small

>>> small.x, small.y
... ?

>>> reload(small)

>>> small.y, y
... ?


1. Quels affichages ?

#!python
# fichier module1.py
prompt = '%'
def printer(x):
  print(prompt,x)
#!python
# fichier module2.py
from module 1 import prompt
def printer(x):
  print(prompt,x)
>>> import module1 as m1


>>> import module2 as m2

>>> m1.prompt = '*'

>>> m2.printer('Hello')
... ?

>>> reload(m2)

>>> m2.printer('Hello')
... ?

>>> reload(m1)

>>> m2.printer('Hello')
... ?

>>> reload(m2)

>>> m2.printer('Hello')
... ?


#!comment
A la différence de C++, qui distingue
variables ordinaires, références, pointeurs.
passage d'arguments par valeur, référence, pointeur.

Bonnes pratiques

  • Fuyez from et reload.
  • Evitez les « globales » (noms définis au plus haut niveau d’un fichier, hors de toute fonction).

Exercice

Écrire un module regroupant des fonctions permettant de manipuler un fichier :

  • count(fichier) : renvoie le nombre de lignes, de mots et de lettres.
  • head(fichier,n) : renvoie les n premières lignes.
  • tail(fichier,n) : renvoie les n dernières lignes.
  • find(fichier,str) : affiche toutes les lignes contenant la chaine str.
  • replace(fichier,str1, str2) : affiche à l’écran toutes les lignes du fichier, en remplaçant chaque occurrence de str1 par str2.

Références

© David Chamont, Laboratoire Leprince-Ringuet (LLR) / IN2P3 / CNRS, Ecole polytechnique / Université Paris-Saclaybr
© Ce(tte) œuvre est mise à disposition selon les termes de la Licence Creative Commons Attribution – Partage dans les Mêmes Conditions 4.0 International [=#license]


Attachments

LangageFonctions

[wiki: Fonctions] [#license ©]

PageOutline

Définir une nouvelle fonction

  • Une fonction est définie par le mot-clé « def », suivit du nom de la fonction, de ses arguments entre parenthèse, et de « : ».
  • Si pas de return, la fonction retourne None.
  • On peut retourner explicitement une séquence, par exemple une série de résultats séparés par des virgules, qui seront groupés dans un tuple.
>>> def divs(x,y):
...   res1 = x/y
...   res2 = x//y
...   return res1, res2
...
  • Une fonction est un objet appelable, que l’on exécute en appliquant des parenthèses (même vides).
>>> print(divs)
<function divs at ...>


>>> divs(2.,3.)
(0.6666666666666666, 0.0)

>>> res1
NameError: name 'res1' is not defined


  • Les variables affectées sont des variables locales à la fonction.
>>> a = 1


>>> def f():
... a = 2
... print(a)
...

>>> f()
2

>>> def g():
... print(a)
...

>>> g()
1


  • Ce n’est pas une pratique recommandée, mais si vous souhaitez faire des affectations à une variable extérieure à la fonction, vous pouvez la déclarer globale :
>>> def h():
...   global a
...   a = 3
...


>>> h()

>>> print(a)
3


Arguments par défaut

  • On peut fournir des valeurs par défaut, en commençant par les derniers arguments.
  • L’expression qui fournit la valeur par défaut est évaluée lors de la définition de la fonction
>>> i = 5


>>> def f(arg=i):
... return arg

>>> i = 6

>>> f()
5


  • ATTENTION DANGER : evitez d’utiliser une valeur par defaut modifiable, car elle n’est évaluée qu’une seule fois puis réutilisée…
>>> def f(a, L=[]):
...     L.append(a)
...     return L


>>> for i in range(3):
... print f(i)
[0]
[0, 1]
[0, 1, 2]


Arguments nommés

  • Lors d’un appel de fonction, on peut placer des arguments nommés en fin de liste.
>>> def test(s, i=2):
...   print s, i


>>> test('abc', 1)
abc 1

>>> test('abc', i=1)
abc 1

>>> test(s='abc', i=1)
abc 1

>>> test(i=1, s='abc')
abc 1

>>> test(s='abc')
abc 2


Arguments non prédéfinis

  • Dans une definition de fonction, l’auteur peut prévoir une variable spéciale pour recueillir une liste d’arguments non prédéfinis, préfixée *.
  • L’auteur peut aussi prévoir une variable spéciale, préfixée ** et placée en dernier, pour recueillir les arguments nommés non prédéfinis.
>>> def func(n,*args,**kw):
...   print 'n:', n
...   print 'args:', args
...   print 'kwargs:', kw
...


>>> func(1,2,3,4,a=5, b=6)
n: 1
args: (2, 3, 4)
kwargs: {'a': 5, 'b': 6}


  • On peut aussi utiliser * et ** pour « dépaquetter » un tuple ou un dictionnaire dans un appel de fonction.
>>> x = (3, 4)


>>> y = {'a': 5, 'b': 6}

>>> func(1,2,*x,**y)
n: 1
args: (2, 3, 4)
kwargs: {'a': 5, 'b': 6}

>>> func(1,2,x,y)
n: 1
args: (2, (3, 4), {'a': 5, 'b': 6})
kwargs: {}


Fonctions intégrées (builtin)

#!python
print(values[,sep=' '][,end='\n'])
input([prompt])
round(x[, n=0])


type(obj) dir([object]) help([object]) repr(obj)
hasttr(object,attribut) isinstance(object,class)

globals() locals() eval(expression)

range([start=0],stop[,step=1])
len(seq) reversed(seq) sorted(seq)
sum(iterable)


#!comment
dir([object]) Retourne une liste des toutes les méthodes et attributs de object s’il est fourni, sinon retourne une liste de tous les objects du contexte courant. Cette fonction est essentiellement utilisée dans l’interpréteur interactif pour tester les objets.
eval(expression) Cette fonction analyse et exécute expression (qui doit être une chaine).
globals() Retourne un dictionnaire représentant les variables présente dans le contexte global.
hasttr(object, attribut) Retourne True si l’objet possède l’attribut en question.
help([object]) Affiche l’aide au sujet d’un objet si object est fourni, sinon affiche l’aide générale. Cette fonction est destinée à être utilisée dans l’interpréteur interactif.
input([prompt]) Si le paramètre prompt est fourni, alors il sera affiché sur la sortie standard. Dans tous les cas, la fonction lit une ligne écrite (dont saisie est interrompue par la touche entrée) et la retourne sous forme de chaine.
isinstance(object, class) Retourne True si object est une instance de class. class peut aussi être un tuple contenant plusieurs classes, et la fonction retournera True si object est une instance de l’un d’entre eux. Il s’agit de LA manière la plus correcte de vérifier le type d’un objet.
len(seq) Retourne la longueur de la séquence seq.
locals() Fait de même que globals(), mais avec le contexte local.
PYTHON 3 : print([obj1, ..., objn][, sep=' '][, end='\n']) Affiche obj1 jusque objn, séparés par sep, en ajoutant end à la fin. sep et end doivent être des chaines.
range([start=0], stop[, step=1]) Retourne un objet range, qui est un objet itérable équivalent à une liste d’entiers, commençant à start et finissant à end - 1, et séparés par le pas sep.
repr(obj) Affiche la représentation (définie par la méthode repr() de obj.
reversed(seq) Retourne l’inverse de la séquence passée en argument. Ceci est équivalent à seq.reverse(), exceptée que cette fonction retourne un nouvel objet, et peut donc être utilisée dans une boucle for.
round(x[, n=0]) Arrondit x à n décimales.
sorted(seq) Retourne une séquence triée à partir de seq. Cette fonction est équivalent à appeler la méthode seq.sort(), excepté le fait qu’elle retourne un nouvel objet (comme reversed()).
sum(iterable) Permet de sommer un itérable contenant uniquement des entiers.
type(obj) Cette fonction retourne la classe de obj. Elle ne devrait être utilisée que dans l’interpréteur interactif.

Exercices

1. Écrire une fonction qui permet de convertir des francs en euros. (1€ = 6.55957F).
1. Écrire une fonction qui calcule le périmètre d’un cercle de rayon R (qui sera donc l’argument). Pour rappel : le périmètre est P = 2×π×R. On pourra prendre π = 3.14 ou, mieux, chercher un module qui contient ce nombre et l’utiliser.

import math
math.pi

1. Écrire une fonction qui prend en argument un nombre n et qui calcule n! (n factorielle), sans utiliser la récursivité. Rappel : n! correspond à la multiplication des n premiers entiers avec la convention que 0! = 1. Ainsi, par exemple, 4! = 1×2×3×4 = 24.
1. Écrire une fonction qui prend deux arguments, l’un d’eux étant une fonction. La première fonction doit appliquer la fonction passée en argument au second argument, et renvoyer le résultat.
1. Écrire une fonction qui prend une date de naissance en argument et qui retourne le nombre de jours écoulés depuis.On pensera aux années bissextiles ; une année est bissextile si : elle est divible par 4 mais par par 100, elle est divisible par 400. On pourra utiliser le module datetime pour obtenir la date du jour courant automatiquement :

from datetime import datetime
today = datetime.today()
today = today.day, today.month, today.year

Références

© David Chamont, Laboratoire Leprince-Ringuet (LLR) / IN2P3 / CNRS, Ecole polytechnique / Université Paris-Saclaybr
© Ce(tte) œuvre est mise à disposition selon les termes de la Licence Creative Commons Attribution – Partage dans les Mêmes Conditions 4.0 International [=#license]


Attachments

LangageModulesQuizz4

Modules Quizz 4

—-

#!python
# fichier module1.py
prompt = '%'
def printer(x):
  print(prompt,x)
#!python
# fichier module2.py
from module1 import prompt
def printer(x):
  print(prompt,x)
>>> import module1 as m1


>>> import module2 as m2


#!html
<br clear=right>

—-

>>> m1.prompt = '*'


>>> m2.printer('Hello')
% Hello


#!html
<br clear=right>

—-

>>> reload(m2)


>>> m2.printer('Hello')

  • Hello

#!html
<br clear=right>

—-

>>> reload(m1)


>>> m2.printer('Hello')

  • Hello

#!html
<br clear=right>

—-

>>> reload(m2)


>>> m2.printer('Hello')
% Hello


#!html
<br clear=right>

—-


Attachments