Bonjour !

J'ai trouvé un design patern dans un boucain qui permet de faire de la programation evenementiel : Observer !

Helas le truc est buggué et me sort une erreur a l'execution ! et je n'arrive pas a la corrigé ... est ce que vous pourriez jeter un coup d'oeil ?

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#!/usr/bin/python
#-*- coding:utf-8 -*-
 
class Event(object):
    """ Classe Evenement """
    def __init__(self,name):
        self.name = name
        self._observateurs = []
 
    def __iadd__(self, observateur):
        """ ajoute un observateur """
        if not callable(observateur):
            raise TypeError("Doit etre un objet appellable")
 
        observateurs = self._observateurs
        if observateur not in observateurs:
            observateurs.append(observateur)
 
        return self
 
    def __isub__(self,observateur):
        """ retire un observateur """
        observateurs = self._observateurs
        if observateur in observateurs:
            observateurs.remove(observateur)
 
        return self
 
    def __call__(self,*args,**kw):
        """ declenche l'événement auprés de tous les inscrits """
        [observateur(*args,**kw) for observateur in self._observateurs]
 
 
class Fenetre(object):
    def __init__(self,name):
        self.name = name
        self.titre = 'titre de la fenetre'
        self.contenu = 'contenu de la fenetre'
        self.titreEvent = Event('titre')
        self.contenuEvent = Event('contenu')
 
    globalTitreEvent = Event('titre global')
 
    def changeTitre(self,titre):
        self.titre = titre
        self.titreEvent(titre)
        Fenetre.globalTitreEvent(titre)
 
    def changeContenu(self,contenu):
        self.titre = contenu
        self.contenuEvent(contenu)
 
class ObservateurTitre(object):
    def __init__(self,fenetre):
        fenetre.titreEvent += self
 
    def __call__(self,titre):
        print 'le titre a été changé en "%s" !' % titre
 
class ObservateurContenu(object):
    def __init__(self,fenetre):
        fenetre.contenuEvent += self
 
    def __call__(self,contenu):
        print 'le contenu a été changé en "%s" !' % contenu
 
class ObservateurGlobal(object):
    def __init__(self,fenetre):
        fenetre.globalTitreEvent += self
 
    def __call__(self,name,titre):
        print 'le titre de "%s" a été changé en "%s" !' % (name,titre)
 
fenetre = Fenetre('fenetre 1')
fenetre2 = Fenetre('fenetre 2')
 
ob1 = ObservateurTitre(fenetre)
ob1 = ObservateurContenu(fenetre)
ob1 = ObservateurGlobal(fenetre)
 
fenetre.changeTitre('nouveau titre')
fenetre.changeContenu('nouveau contenu')
fenetre2.changeTitre('nouveau titre2')
et le rendu console :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
le titre a été changé en "nouveau titre" !
Traceback (most recent call last):
  File "/home/anthyme/workspace/MyLibs/Python/design partern/observer.py", line 81, in ?
    fenetre.changeTitre('nouveau titre')
  File "/home/anthyme/workspace/MyLibs/Python/design partern/observer.py", line 47, in changeTitre
    Fenetre.globalTitreEvent(titre)
  File "/home/anthyme/workspace/MyLibs/Python/design partern/observer.py", line 31, in __call__
    [observateur(*args,**kw) for observateur in self._observateurs]
TypeError: __call__() takes exactly 3 arguments (2 given)
Ca veux dire qu'on ne peux pas renvoyer *args, **kw dans l'entrée d'une autre fonction ?

merci !