Python Avancé
Ernesto Revilla
Logiciel Intégré pour le Contrôle des Entreprises, s.l.
GCubo : Groupe d'utilisateurs de GNU/Linux de Grenade
[Link]. Informatique (Univ. Grenade)
Avril 2004
GCubo : Groupe d'utilisateurs de GNU/Linux de Grenade
Héritage simple depuis des types internes
Python, depuis la version 2.2, permet d'hériter de types de données internes,
comme
●
int, float, complex, str, unicode
●
list, dict, tuple
classe DefaultDict(dict):
def __init__(self, valeursInitiales=None, parDéfaut=0.0):
dict.__init__(initialValues ou {})
self._default=default
def __getitem__(self, clé):
essayer :
return dict.__getitem__(self, key)
excepté KeyError :
return self._default
si __name__=="__main__":
d=DefaultDict({'a': 5})
imprimer 'valeur de e :', d['e']
print 'valeur de a:', d['a']
Voir [Link]
GCubo : Groupe d'utilisateurs de GNU/Linux de Grenade
Simuler des types internes 1
Il existe des constructions syntaxiques qui facilitent la rédaction des programmes,
comme [ ], { }, !=, ... Nous pouvons personnaliser leur comportement.
Nous avons réalisé un dictionnaire par délégation :
classe MiDicc :
def __init__(self, diccInicial=None):
self._dicc=dict(diccInicial ou {})
def __getitem__(self, item):
print "lisant", item
return self._dicc[item]
def __setitem__(self, item, valor):
print "établissant", item
self._dicc[item]=valor
def zap(self):
self._dicc={}
def __getattr__(self, attr):
si attr dans ['items', 'keys', 'values'] :
return getattr(self._dicc, attr)
Voir [Link].
GCubo : Groupe d'utilisateurs de GNU/Linux de Grenade
Simuler des types internes 2
Utiliser les entrées du dictionnaire comme attributs :
classe MiDicc2(MiDicc):
def __getattr__(self, attr):
return MiDicc.__getitem__(self, attr)
def __setattr__(self, attr, valeur):
MiDicc.__setitem__(self, attr, valor)
produire un boucle infinie !!, en définissant l'attribut _dicc dans MiDicc
def __setattr__(self, attr, valor):
si attr n'est pas dans ['_dicc']:
MiDicc.__setitem__(self, attr, valeur)
sinon :
MiDicc.__dict__['_dicc']=valeur
# si MiDicc avait hérité de l'objet
# MiDicc.__setattr__(self, attr, valeur)
Voir [Link].
GCubo : Groupe d'utilisateurs de GNU/Linux de Grenade
Un exemple pratique
Pour cet exemple, il est nécessaire d'avoir la base de données [Link]),
comme également le binding pour python ([Link]).
Connexion à une base de données sqlite :
importer sqlite
con=[Link]('[Link]')
cur=[Link]()
def creerTableau():
[Link]("créer une table personas (num entier, "
"nombre text, "apellidos text, edad integer;")
def insererDonneesExemple():
personas=[ [1, 'Erny', 'Revilla'], [2, 'Lorenzo', 'Gil'],
[3, 'Dani', 'Molina']]
pour persona dans personas :
[Link]("insérer dans personas (num, nom, "
apellidos) valeurs (%s, '%s', '%s');
Voir les fichiers [Link], [Link] et [Link] qui montrent comment créer un
petite couche de persistance pour les objets.
GCubo : Groupe d'utilisateurs de GNU/Linux de Grenade
Choses sur __init__
●
__init__ representa el método de inicialización de instancia, no es el
initialiseur (comme en c++) au lieu du constructeur.
●
__init__ est appelé après que la mémoire a été réservée et réalisée
une initialisation minimale de l'objet.
● Lors de la réalisation d'une héritage multiple, il est nécessaire de définir __init__ pour indiquer le
ordre des appels de __init__ des superclasses
classe A(object):
def __init__(self):
__init__ de A
classe B(object):
def __init__(self):
__init__ de B
classe C(A,B): passer # ça c'est mal !!!
c=C()
classe C(A,B):
def __init__(self):
A.__init__(self)
B.__init__(self)
Voir [Link] GCubo : Groupe d'utilisateurs de GNU/Linux de Grenade
__new__, le constructeur
● __new__ est toujours une méthode de classe
●
__new__ apparaît dans la version 2.2 de Python
● avec __new__, on peut également retourner des instances d'autres types.
Exemples :
classe A(object):
def __init__(self, *args, **kwargs):
création d'un objet de type A avec
arguments pos. %s et arguments nommés %s
% (args, kwargs)
# retourner d'autres types d'objets
classe B(object):
def __new__(cls, *args, **kwargs):
return A(*args, **kwargs)
x=B(1,2, pepe='no')
Voir [Link]
GCubo : Groupe d'utilisateurs de GNU/Linux de Grenade
__new__: singleton
# singleton:
classe Singleton(objet):
_instance=None
def __new__(cls, *args, **kwargs):
si pas cls._instance :
Création d'un Singleton
cls._instance=object.__new__(cls, *args,
**kwargs)
return cls._instance
def __init__(self, *args, **kwargs):
Initialisation du Singleton
s=Singleton()
s=Singleton()
GCubo : Groupe d'utilisateurs de GNU/Linux de Granada
Métaclasses
●
À la fin de la lecture de la définition d'une classe, Python la crée en utilisant
une métaclasse de forme Métaclasse(nom, superclasses, dictionnaire)
●
Nom est le nom de la classe, Superclasses est un tuple
●
dictionnaire contient les fonctions et identifiants définis dans
cours
● Actuellement (>=2.2), utilise deux métaclasses, une pour les anciennes classes
([Link]) y une pour les nouvelles (type)
● Dans la métaclasse, nous pouvons définir de nouveaux attributs ou fonctions pour la classe
classe Metaclase(type):
def __init__(self, nom, bases, dic):
type.__init__(self, nom, bases, dic)
Définissant la classe %s :
imprimer "Bases: %s" % (bases ou None)
imprimer "Dict: %s" % dic
classe A(object):
__metaclass__=Metaclase
_attributes=["at1","at2","at3"]
y=5
def __init__(self):
self.x=10 GCubo : Groupe d'utilisateurs de GNU/Linux de Grenade
Métaclasses 2
Voir [Link] pour l'exemple précédent.
L'exemple suivant crée de nouvelles méthodes dans une classe (getters et setters) pour
les attributs spécifiés.
classe Metaclasse(type):
def __init__(self, nom, bases, dic):
type.__init__(self, nom, bases, dic)
si "_attributes" dans dic :
pour attr dans dic['_attributes'] :
f=lambda s,a=attr: getattr(s,a)
setattr(self, 'get' + attr, f)
f=lambda s, valeur, a=attr: setattr(s,a,valeur)
setattr(self, 'set'+attr, f)
Voir [Link]
GCubo : Groupe d'utilisateurs de GNU/Linux de Grenade