Modifications entre les versions 1 et 29 (s'étendant sur 28 versions)
Version 1 à la date du 2012-02-23 23:02:59
Taille: 1010
Éditeur: DavinBaragiotta
Commentaire: première ébauche
Version 29 à la date du 2012-08-27 07:27:18
Taille: 14120
Éditeur: DavinBaragiotta
Commentaire:
Texte supprimé. Texte ajouté.
Ligne 10: Ligne 10:
  * utiliser la bibliothèque standard et des packages existants
Ligne 11: Ligne 12:
  * utiliser la bibliothèque et des packages existants
Ligne 15: Ligne 15:
== NOTIONS INTERMÉDIAIRES ==

=== Orienté-objet et classes ===

==== Objet, instance de classe ====

==== Attributs et méthodes ====

==== Héritage ====

==== self ====

==== CRUD ====

==== __init__ ====

=== Décorateurs ===

=== Exceptions ===

=== Lambda ===

=== Bibliothèque standard ===
== STANDARD LIBRARY ET PACKAGES ==

=== Bibliothèque standard (standard library) ===

Modules explorés ou abordés pendant ateliers AUF :
Ligne 40: Ligne 21:
 * re
 * os.system
 * os.popen
 * os.path
Ligne 46: Ligne 23:
 * re

Modules potentiellement utiles pour administrateurs système :
 * subprocess {{{
import subprocess
out = subprocess.call("grep -rsn 'davin' . > ~/Bureau/davin", shell=True)
print out

resultat = subprocess.Popen("grep -rsn 'davin' .", shell=True, stdout=subprocess.PIPE).communicate()[0]
type(resultat)
print resultat
}}}
  * shell=True pour commande juste en un string
 * pwd {{{
# http://www.python.org/doc/lj21.html
import posix
import pwd
pwd.getpwall()
print 'hello', pwd.getpwuid(posix.getuid())[0]
# progfou: et autre détail non négligeable pour nous à l'AuF : pwd fait des appels à la libc, qui passe par NSS, donc ça donne aussi les comptes réseau
}}}
 * socket {{{
# socket.getaddrinfo pour faire de la résolution DNS
import socket
socket.getaddrinfo('smtp.sn.auf.org', 25)
}}}
 * os.path
 * sys

Autres modules d'intérêt :
 * os.system
Ligne 54: Ligne 62:
 * sys
 * socket
Ligne 59: Ligne 65:
 * pypi
  * http://pypi.python.org/
  * http://pypi.auf.org/
pypi
 * http://pypi.python.org/
  * numpy, scipy {{{
# fonctions d'optimisation

def f(x) :
   return x**3 - x**2 -10

from scipy import optimize
optimize.fsolve(f, 1)
}}}
  [[http://dakarlug.org/pat/scientifique/html/|Python African Tour (Dakar, 2009) : Informatique scientifique avec Python]]
  * android
   * [[http://forum.frandroid.com/topic/1519-tuto-programmer-en-python-v26-sur-un-telephone-android/|Tutoriel en français]] (2009)
  * nltk
  * jabberbot
  * django

http://pypi.auf.org/
  * auf.django.references

autres
  * [[http://www.slideshare.net/ffunction/fabric-cuisine-and-watchdog-for-server-administration-in-python|Fabric, Cuisine, Watchdog]]
  * [[http://code.google.com/p/pyo/|pyo]] {{{
from pyo import *
s = Server().boot()
s.start()
wav = SquareTable()
env = CosTable([(0,0), (100,1), (500,.3), (8191,0)])
met = Metro(.125, 12).play()
amp = TrigEnv(met, table=env, mul=.1)
pit = TrigXnoiseMidi(met, dist='loopseg', x1=20, scale=1, mrange=(48,84))
out = Osc(table=wav, freq=pit, mul=amp).out()
s.stop()
}}}

== CLASSES ET OBJETS ==

En Python, tout est un objet... on veut donc pouvoir créer nos propres objets en Python.

=== Classe et objets : structure et données ===

 * Les classes sont une structure, un type de données
 * Les objets sont les données, les variables de ce type
 * Schéma :
  * Monde : objets réels (ou concepts)
  * Modélisation du domaine : conceptualisations, (pseudo) UML
  * Modélisation informatique : '''classes'''
  * Données : '''objets''' virtuels

=== Attributs et méthodes ===

 * La classe est du code informatique qui
  * structure les données : '''attributs'''
   ''un peu comme une table de DB a une structure : colonnes''
  * déclare des traitements possibles sur ces données : '''méthodes''' (fonctions dans classe)
   ''un peu comme une DB a traitement informatique possible sur données : procédures stockées''

 * '''méthodes''' : fonctions, donc callable
 * '''attributs''' : variables
 * nom des attributs et méthodes : visible dans introspection

=== Créer une Classe ===

{{{
class Personne():
    pass
}}}
 * class
 * convention de nommage : CamelCase
  * PersonneMorale : ok
  * personne_morale : pas ok

=== self ===

 * représente l'objet ''en cours'' dans le code de la Classe
 * nom générique : veut dire "quelque soit l'objet ''en cours'', voici ce que je veux faire de '''cet''' objet"
 * équivalent à '''this''' en Java ou PHP

=== Créer méthode d'initialisation d'objet ===

{{{
class Personne():
    def __init__(self, nom, prenom=""):
        self.nom = nom
        self.prenom = prenom
}}}

 * self : toujours comme premier argument
 * autres paramètres reçus lors d'initialisation (nom, prenom) sont stockés sur l'objet
 * les attributs 'nom' et 'prenom' sur l'objet : self.nom, self.prenom, sont des variables avant une valeur propre à l'objet

=== Créer une (autre) méthode ===

{{{
class Personne():
    def __init__(self, nom, prenom=""):
        self.nom = nom
        self.prenom = prenom

    def nom_complet(self):
        return "%s %s" % (self.nom.upper(), self.prenom)
}}}

 * Convention de nommage : lower_case
  * NomComplet : pas ok
  * nom_complet : ok
 * self : premier paramètre
 * tout le reste : c'est simplement une fonction
  (paramètres en input, traitement, return pour output)

=== CRUD d'objets ===

 * '''Create''' : création d'objet {{{
davin = Personne(nom="Baragiotta", prenom="Davin")
}}}
 On utilise la classe pour créer un objet de cette classe.
 On passe en paramètre les infos nécessaires à {{{__init__()}}} pour créer l'objet.
  * vérification des attributs de l'objet davin {{{
davin. [+ tab] # ipython
davin.nom
davin.prenom
}}}
 * '''Update''' : modification de l'objet {{{
davin.prenom = "Daniel"
davin.prenom
}}}
 * '''Delete''' : suppression de l'objet {{{
del davin
}}}
 * '''Retrieve''' : récupération de l'objet n'a pas de sens si on a de la permanence de l'information.
  Typiquement, on voudra stocker nos objets dans des bases de données en liant nos Classes à des tables.
  C'est ce que les ORM (Object-relational-mapper) font.
  Atelier Django montre comment récupérer les objets stockés dans DB.

=== Attributs et méthodes : de classe et d'objet ===

Dans l'exemple précédant, nous avons vu les attributs et méthodes d'un '''objet''' :

 * objet.attribut {{{
davin.nom
}}}
 * objet.methode() {{{
davin.nom_complet()
}}}

Il existe aussi des attributs et méthodes de '''classe''' : {{{
class Personne():
    """Représente les personnes"""
    definition = "Une personne est un individu physique, un humain quoi!"
    
    def __init__(self, nom, prenom=""):
        self.nom = nom
        self.prenom = prenom
        
    def nom_complet(self):
        return "%s %s" % (self.nom.upper(), self.prenom)
    
    @staticmethod
    def wordnet_synonyme():
        wordnet_syn = "Individual" # fake ;)
        return wordnet_syn
}}}

 * Classe.attribut {{{
Personne.definition
}}}
 * Classe.methode() {{{
Personne.wordnet_synonyme()
}}}

Il est à noter que :
 * l'attribut de '''classe''' est déclaré directement sous la classe...
  ... pas dans la méthode {{{__init__()}}} : car cet attribut n'est pas propre à un objet
 * la méthode de '''classe''' ne prend pas l'argument : '''self'''
 * pour déclarer une méthode de classe, il faut utiliser le '''décorateur''' @staticmethod

 * tous les '''objets''' d'une classe ont accès aux attributs et méthodes (génériques) de la '''classe'''.
 * la classe, par contre, n'a accès qu'a ses propres attributs et méthodes.

{{{
davin = Personne(nom="Baragiotta", prenom="Davin")
pascal = Personne(nom="Bou Nassar", prenom="Pascal")

davin.definition
'Une personne est un individu physique, un humain quoi!'

pascal.definition
'Une personne est un individu physique, un humain quoi!'

Personne.definition
'Une personne est un individu physique, un humain quoi!'

davin.definition == pascal.definition == Personne.definition
True

davin.wordnet_synonyme()
'Individual'

pascal.wordnet_synonyme()
'Individual'

In [11]: Personne.nom
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)

/home/giotta/Bureau/<ipython console> in <module>()

AttributeError: class Personne has no attribute 'nom'

In [12]: Personne.prenom
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)

/home/giotta/Bureau/<ipython console> in <module>()

AttributeError: class Personne has no attribute 'prenom'

In [13]: Personne.nom_complet()
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)

/home/giotta/Bureau/<ipython console> in <module>()

TypeError: unbound method nom_complet() must be called with Personne instance as first argument (got nothing instead)

}}}

=== Héritage ===

On peut créer une hiérarchie de classe, avec des SousClasse qui hérite des ClasseParent.

==== Syntaxe d'héritage ====

 * On déclare les classes héritées en paramètre de la classe (entre les parenthèses de la définition de classe).
 * La classe suprême en Python est la classe '''object'''.
 * On peut donc faire hériter nos classes de cet objet au sommet de la hiérarchie {{{
class Personne(object):
    pass

class Chat():
    pass

Chat. [+tab] # ipython
Personne. [+tab] # ipython
}}}
 * dans cet exemple, on voit que Personne a plus de noms (attributs, méthodes) dans son espace de nom...
 * ... Personne a hérité des attributs et méthodes de '''object'''

==== Attributs et méthodes de ClasseParent sont hérités ====

 * Une sous-classe hérite donc des attributs et méthodes de sa classe parent {{{
class Personne(object):
    """Représente les personnes"""
    definition = "Une personne est un individu physique, un humain quoi!"
    
    def __init__(self, nom, prenom=""):
        self.nom = nom
        self.prenom = prenom
        
    def nom_complet(self):
        return "%s %s" % (self.nom.upper(), self.prenom)
    
    @staticmethod
    def wordnet_synonyme():
        wordnet_syn = "Individual" # fake ;)
        return wordnet_syn

class Professeur(Personne):
    pass

Personne. [+tab] # ipython
Professeur. [+tab] # ipython
}}}

==== __init__() d'une SousClasse ====

 * si une classe hérite :
  * son {{{__init__()}}} '''doit''' appeler {{{__init__()}}} de son parent
  * en passant bien tous les arguments requis par la ClasseParent...
  * ... incluant '''self'''

{{{
class Personne():
    """Représente les personnes"""
    definition = "Une personne est un individu physique, un humain quoi!"

    def __init__(self, nom, prenom=""):
        self.nom = nom
        self.prenom = prenom

    def nom_complet(self):
        return "%s %s" % (self.nom.upper(), self.prenom)

    @staticmethod
    def wordnet_synonyme():
        wordnet_syn = "Individual" # fake ;)
        return wordnet_syn

class Professeur(Personne):
    def __init__(self, nom, prenom="", universite=""):
        self.universite = universite
        Personne.__init__(self, nom, prenom)

In [2]: davin = Personne(nom="Baragiotta", prenom="Davin")

In [3]: prof = Professeur(nom="Lemay", prenom="Paul", universite="UQAM")

In [4]: prof.
prof.__class__ prof.__module__ prof.nom_complet prof.wordnet_synonyme
prof.__doc__ prof.definition prof.prenom
prof.__init__ prof.nom prof.univesite

In [5]: davin.
davin.__class__ davin.__module__ davin.nom_complet
davin.__doc__ davin.definition davin.prenom
davin.__init__ davin.nom davin.wordnet_synonyme
}}}

== AUTRES NOTIONS PYTHON ==

=== Décorateurs ===

Les décorateurs sont des fonctions qui "wrappent" d'autres fonctions :
 * ils permettent notamment de contrôler l'accès aux fonctions wrappées
 * mais pourraient aussi modifier input et output de ces fonctions

Exemple de décorateur conçu pour contrôler l'accès : {{{is_admin}}}

{{{
def is_admin(fn):
    def inner(admin, *args, **kwargs):
        if admin:
            return fn(*args, **kwargs)
        else :
            return "Nope"
    return inner

@is_admin
def salut(nom):
    return "salut %s" % nom
}}}

Pour décorer une fonction : décorer avec {{{@nom_fonction_qui_decore}}}

Il faut appeler la fonction décorée aussi avec les paramètres requis par la fonction qui décore.
{{{
In [10]: admin = True

In [11]: salut(admin, 'Davin')
Out[11]: 'salut Davin'

In [12]: admin = False

In [13]: salut(admin, 'Davin')
Out[13]: 'Nope'
}}}

=== Exceptions ===

Pour gérer les exceptions qui peuvent être levées lors de l'exécution du code...
 ... il faut utiliser la structure du langage : '''try''' et '''except'''
{{{
In [18]: davin = Personne(nom="Baragiotta", prenom="Davin")

In [19]: davin.nationalite
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)

/home/giotta/Bureau/<ipython console> in <module>()

AttributeError: Personne instance has no attribute 'nationalite'

In [20]: try:
   ....: davin.nationalite
   ....: except AttributeError:
   ....: davin.nationalite = None
   ....:
   ....:

In [21]: davin.nationalite

In [22]:

}}}

 * après le mot '''except''' on fournit le type d'exception qu'on veut gérer, ex.: {{{AttributeError}}}
Ligne 67: Ligne 457:
* modifier iptables  * créer une classe Personne
 * créer une méthode nom_complet() (ou fullname() ) sur la classe Personne retournant le nom complet d'un personne
 * créer une classe Professeur qui hérite de Personne
 * créer un attribut "formations" pour les objets de la classe Professeur : c'est la liste des formations que donne le prof
 * tester comment ajouter ou supprimer une formation à un professeur : quelle approche la plus simple?
  * créer une méthode Professeur.ajout_formation() ?
  * ou simplement exploiter les méthodes de liste : Professeur.formations.append() ?

Python : Atelier intermédiaire


INTRODUCTION

  • Objectifs :
    • utiliser la bibliothèque standard et des packages existants
    • savoir coder ses propres objets


STANDARD LIBRARY ET PACKAGES

Bibliothèque standard (standard library)

Modules explorés ou abordés pendant ateliers AUF :

  • datetime
  • pickle
  • sqlite3
  • re

Modules potentiellement utiles pour administrateurs système :

  • subprocess

    import subprocess
    out = subprocess.call("grep -rsn 'davin' . > ~/Bureau/davin", shell=True)
    print out
    
    resultat = subprocess.Popen("grep -rsn 'davin' .", shell=True, stdout=subprocess.PIPE).communicate()[0]
    type(resultat)
    print resultat
    • shell=True pour commande juste en un string
  • pwd

    # http://www.python.org/doc/lj21.html
    import posix
    import pwd
    pwd.getpwall()
    print 'hello', pwd.getpwuid(posix.getuid())[0]
    # progfou: et autre détail non négligeable pour nous à l'AuF : pwd fait des appels à la libc, qui passe par NSS, donc ça donne aussi les comptes réseau
  • socket

    # socket.getaddrinfo pour faire de la résolution DNS
    import socket
    socket.getaddrinfo('smtp.sn.auf.org', 25)
  • os.path
  • sys

Autres modules d'intérêt :

  • os.system
  • zlib
  • csv
  • json
  • email
  • uuid
  • urllib
  • gettext
  • pdb

Packages

pypi

http://pypi.auf.org/

  • auf.django.references

autres

  • Fabric, Cuisine, Watchdog

  • pyo

    from pyo import *
    s = Server().boot()
    s.start()
    wav = SquareTable()
    env = CosTable([(0,0), (100,1), (500,.3), (8191,0)])
    met = Metro(.125, 12).play()
    amp = TrigEnv(met, table=env, mul=.1)
    pit = TrigXnoiseMidi(met, dist='loopseg', x1=20, scale=1, mrange=(48,84))
    out = Osc(table=wav, freq=pit, mul=amp).out()
    s.stop()

CLASSES ET OBJETS

En Python, tout est un objet... on veut donc pouvoir créer nos propres objets en Python.

Classe et objets : structure et données

  • Les classes sont une structure, un type de données
  • Les objets sont les données, les variables de ce type
  • Schéma :
    • Monde : objets réels (ou concepts)
    • Modélisation du domaine : conceptualisations, (pseudo) UML
    • Modélisation informatique : classes

    • Données : objets virtuels

Attributs et méthodes

  • La classe est du code informatique qui
    • structure les données : attributs

      • un peu comme une table de DB a une structure : colonnes

    • déclare des traitements possibles sur ces données : méthodes (fonctions dans classe)

      • un peu comme une DB a traitement informatique possible sur données : procédures stockées

  • méthodes : fonctions, donc callable

  • attributs : variables

  • nom des attributs et méthodes : visible dans introspection

Créer une Classe

class Personne():
    pass

self

  • représente l'objet en cours dans le code de la Classe

  • nom générique : veut dire "quelque soit l'objet en cours, voici ce que je veux faire de cet objet"

  • équivalent à this en Java ou PHP

Créer méthode d'initialisation d'objet

class Personne():
    def __init__(self, nom, prenom=""):
        self.nom = nom
        self.prenom = prenom
  • self : toujours comme premier argument
  • autres paramètres reçus lors d'initialisation (nom, prenom) sont stockés sur l'objet
  • les attributs 'nom' et 'prenom' sur l'objet : self.nom, self.prenom, sont des variables avant une valeur propre à l'objet

Créer une (autre) méthode

class Personne():
    def __init__(self, nom, prenom=""):
        self.nom = nom
        self.prenom = prenom

    def nom_complet(self):
        return "%s %s" % (self.nom.upper(), self.prenom)
  • Convention de nommage : lower_case
  • self : premier paramètre
  • tout le reste : c'est simplement une fonction
    • (paramètres en input, traitement, return pour output)

CRUD d'objets

  • Create : création d'objet

    davin = Personne(nom="Baragiotta", prenom="Davin")
    On utilise la classe pour créer un objet de cette classe.

    On passe en paramètre les infos nécessaires à __init__() pour créer l'objet.

    • vérification des attributs de l'objet davin

      davin. [+ tab] # ipython
      davin.nom
      davin.prenom
  • Update : modification de l'objet

    davin.prenom = "Daniel"
    davin.prenom
  • Delete : suppression de l'objet

    del davin
  • Retrieve : récupération de l'objet n'a pas de sens si on a de la permanence de l'information.

    • Typiquement, on voudra stocker nos objets dans des bases de données en liant nos Classes à des tables. C'est ce que les ORM (Object-relational-mapper) font. Atelier Django montre comment récupérer les objets stockés dans DB.

Attributs et méthodes : de classe et d'objet

Dans l'exemple précédant, nous avons vu les attributs et méthodes d'un objet :

  • objet.attribut

    davin.nom
  • objet.methode()

    davin.nom_complet()

Il existe aussi des attributs et méthodes de classe :

class Personne():
    """Représente les personnes"""
    definition = "Une personne est un individu physique, un humain quoi!"
    
    def __init__(self, nom, prenom=""):
        self.nom = nom
        self.prenom = prenom
        
    def nom_complet(self):
        return "%s %s" % (self.nom.upper(), self.prenom)
    
    @staticmethod
    def wordnet_synonyme():
        wordnet_syn = "Individual" # fake ;)
        return wordnet_syn
  • Classe.attribut

    Personne.definition
  • Classe.methode()

    Personne.wordnet_synonyme()

Il est à noter que :

  • l'attribut de classe est déclaré directement sous la classe...

    • .. pas dans la méthode __init__() : car cet attribut n'est pas propre à un objet

  • la méthode de classe ne prend pas l'argument : self

  • pour déclarer une méthode de classe, il faut utiliser le décorateur @staticmethod

  • tous les objets d'une classe ont accès aux attributs et méthodes (génériques) de la classe.

  • la classe, par contre, n'a accès qu'a ses propres attributs et méthodes.

davin = Personne(nom="Baragiotta", prenom="Davin")
pascal = Personne(nom="Bou Nassar", prenom="Pascal")

davin.definition
'Une personne est un individu physique, un humain quoi!'

pascal.definition
'Une personne est un individu physique, un humain quoi!'

Personne.definition
'Une personne est un individu physique, un humain quoi!'

davin.definition == pascal.definition == Personne.definition
True

davin.wordnet_synonyme()
'Individual'

pascal.wordnet_synonyme()
'Individual'

In [11]: Personne.nom
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)

/home/giotta/Bureau/<ipython console> in <module>()

AttributeError: class Personne has no attribute 'nom'

In [12]: Personne.prenom
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)

/home/giotta/Bureau/<ipython console> in <module>()

AttributeError: class Personne has no attribute 'prenom'

In [13]: Personne.nom_complet()
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)

/home/giotta/Bureau/<ipython console> in <module>()

TypeError: unbound method nom_complet() must be called with Personne instance as first argument (got nothing instead)

Héritage

On peut créer une hiérarchie de classe, avec des SousClasse qui hérite des ClasseParent.

Syntaxe d'héritage

  • On déclare les classes héritées en paramètre de la classe (entre les parenthèses de la définition de classe).
  • La classe suprême en Python est la classe object.

  • On peut donc faire hériter nos classes de cet objet au sommet de la hiérarchie

    class Personne(object):
        pass
    
    class Chat():
        pass
    
    Chat. [+tab] # ipython
    Personne. [+tab] # ipython
  • dans cet exemple, on voit que Personne a plus de noms (attributs, méthodes) dans son espace de nom...
  • ... Personne a hérité des attributs et méthodes de object

Attributs et méthodes de ClasseParent sont hérités

  • Une sous-classe hérite donc des attributs et méthodes de sa classe parent

    class Personne(object):
        """Représente les personnes"""
        definition = "Une personne est un individu physique, un humain quoi!"
        
        def __init__(self, nom, prenom=""):
            self.nom = nom
            self.prenom = prenom
            
        def nom_complet(self):
            return "%s %s" % (self.nom.upper(), self.prenom)
        
        @staticmethod
        def wordnet_synonyme():
            wordnet_syn = "Individual" # fake ;)
            return wordnet_syn
    
    class Professeur(Personne):
        pass
    
    Personne. [+tab] # ipython
    Professeur. [+tab] # ipython

__init__() d'une SousClasse

  • si une classe hérite :
    • son __init__() doit appeler __init__() de son parent

    • en passant bien tous les arguments requis par la ClasseParent...

    • ... incluant self

class Personne():
    """Représente les personnes"""
    definition = "Une personne est un individu physique, un humain quoi!"

    def __init__(self, nom, prenom=""):
        self.nom = nom
        self.prenom = prenom

    def nom_complet(self):
        return "%s %s" % (self.nom.upper(), self.prenom)

    @staticmethod
    def wordnet_synonyme():
        wordnet_syn = "Individual" # fake ;)
        return wordnet_syn

class Professeur(Personne):
    def __init__(self, nom, prenom="", universite=""):
        self.universite = universite
        Personne.__init__(self, nom, prenom)

In [2]: davin = Personne(nom="Baragiotta", prenom="Davin")

In [3]: prof = Professeur(nom="Lemay", prenom="Paul", universite="UQAM")

In [4]: prof.
prof.__class__         prof.__module__        prof.nom_complet       prof.wordnet_synonyme
prof.__doc__           prof.definition        prof.prenom            
prof.__init__          prof.nom               prof.univesite 

In [5]: davin.
davin.__class__         davin.__module__        davin.nom_complet       
davin.__doc__           davin.definition        davin.prenom            
davin.__init__          davin.nom               davin.wordnet_synonyme 

AUTRES NOTIONS PYTHON

Décorateurs

Les décorateurs sont des fonctions qui "wrappent" d'autres fonctions :

  • ils permettent notamment de contrôler l'accès aux fonctions wrappées
  • mais pourraient aussi modifier input et output de ces fonctions

Exemple de décorateur conçu pour contrôler l'accès : is_admin

def is_admin(fn):
    def inner(admin, *args, **kwargs):
        if admin:
            return fn(*args, **kwargs)
        else :
            return "Nope"
    return inner

@is_admin
def salut(nom):
    return "salut %s" % nom

Pour décorer une fonction : décorer avec @nom_fonction_qui_decore

Il faut appeler la fonction décorée aussi avec les paramètres requis par la fonction qui décore.

In [10]: admin = True

In [11]: salut(admin, 'Davin')
Out[11]: 'salut Davin'

In [12]: admin = False

In [13]: salut(admin, 'Davin')
Out[13]: 'Nope'

Exceptions

Pour gérer les exceptions qui peuvent être levées lors de l'exécution du code...

  • .. il faut utiliser la structure du langage : try et except

In [18]: davin = Personne(nom="Baragiotta", prenom="Davin")

In [19]: davin.nationalite
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)

/home/giotta/Bureau/<ipython console> in <module>()

AttributeError: Personne instance has no attribute 'nationalite'

In [20]: try:
   ....:     davin.nationalite
   ....: except AttributeError:
   ....:     davin.nationalite = None
   ....:     
   ....:     

In [21]: davin.nationalite

In [22]: 
  • après le mot except on fournit le type d'exception qu'on veut gérer, ex.: AttributeError


EXERCICE

  • créer une classe Personne
  • créer une méthode nom_complet() (ou fullname() ) sur la classe Personne retournant le nom complet d'un personne
  • créer une classe Professeur qui hérite de Personne
  • créer un attribut "formations" pour les objets de la classe Professeur : c'est la liste des formations que donne le prof
  • tester comment ajouter ou supprimer une formation à un professeur : quelle approche la plus simple?
    • créer une méthode Professeur.ajout_formation() ?
    • ou simplement exploiter les méthodes de liste : Professeur.formations.append() ?


CONCLUSION

  • ne pas réinventer la roue : utiliser l'existant
  • DIY (do-it-yourself) : pour le reste, faites du "sur mesure"
  • yalla!

Ateliers/2012-02-24/Python/Plan (dernière édition le 2012-08-27 07:27:18 par DavinBaragiotta)