IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Executer du code après un return ?


Sujet :

Python

  1. #1
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut Executer du code après un return ?
    Bonjour,

    Existe t'il une astuce pour exécuter du code après un return ?

    Je m'explique.
    Dans le cadre d'une instantiation je cherche à lire le namespace globals au sein même de l'instance. Hors c'est Python qui ajoute mon instance dans ce namespace via le key=instance.

    Dans le cadre des deux codes suivants l'__init__ est bien exécuté mais tant que Python n'as pas le retour d'__init__, soit l'instance, il n'y as pas d'entrée dans le globals().

    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
    class metavarclass(type):
        def __new__(cls, name, bases, dct):
            print "Allocation mémoire pour la class", name
            return type.__new__(cls, name, bases, dct)
     
        def __init__(self, name, bases, dct):
            super(metavarclass, self).__init__(name, bases, dct)
            print "Init de la class", self
     
    class varclass(object):
     
        __metaclass__ = metavarclass
     
        def __init__(self):
            self._name = None
     
        def getmyname(self):
            for keys in (keys for keys, values in globals().items() if values == self):
                print 'valeur trouvée', keys
                self._name=keys
     
    a=varclass()
    print "Après l'instanciation", a.getmyname()
    Ou

    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
    class varname(object):
        def getname(function):
            def mon_init(*args, **kwargs):
                instance = args[0]
                function(*args, **kwargs)
                print "Après l'init et dans getname:", instance.getmyname()
            return mon_init
     
        @getname
        def __init__(self):
            print 'Init de varname'
            self._name=None
     
        def getmyname(self):
            for keys in (keys for keys, values in globals().items() if values == self):
                print 'valeur trouvée:', keys
                self._name=keys
     
    a=varname()
    print "Après l'instanciation.", a.getmyname()
    Avez vous une idée ? (Ou je me plante ?)

    Merci

  2. #2
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    758
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

    Informations professionnelles :
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 758
    Points : 970
    Points
    970
    Par défaut
    bonjour,

    selon moi (à prendre avec les précautions qui s'imposent :p) l'instruction:

    crée dans un premier temps l'instance correspondante et ensuite lie dans la portée globale le nom 'a' à cette instance.

    par conséquent, quelque soit la personnalisation de la création de l'instance, cela ne change en rien le fait que le nom soit lié après.

    En revanche tu peux arriver à faire quelque chose si la variable 'a' est associée à une classe que tu contrôles:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    class Toto(object):
        pass
    t = Toto()
    t.a = varname()

  3. #3
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 356
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 356
    Points : 36 884
    Points
    36 884
    Par défaut
    Salut,
    Citation Envoyé par kango Voir le message
    En revanche tu peux arriver à faire quelque chose si la variable 'a' est associée à une classe que tu contrôles
    Pour insister sur "que tu contrôles".
    Python étant "dynamique", il est très facile de faire un "mock" i.e. remplacer un objet par un proxy à sa sauce qui pourra 'wrapper' les accès aux attributs de l'object "original".

    L'objet qui nous intéresse ici étant le __dict__ du module courant, nous pourrions imaginer de le "mocker" par un truc à nous qui ressemble à.
    *but* ce __dict__ là est malheureusement 'readonly'.
    Note: Ca limite les dégâts quand même...
    - W

  4. #4
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Bonjour,

    Citation Envoyé par kango Voir le message
    selon moi (à prendre avec les précautions qui s'imposent :p) l'instruction:

    crée dans un premier temps l'instance correspondante et ensuite lie dans la portée globale le nom 'a' à cette instance.

    par conséquent, quelque soit la personnalisation de la création de l'instance, cela ne change en rien le fait que le nom soit lié après.
    C'est bien ce que j'ai compris aussi kango. C'est le a=b() qui fait que a:b existe dans le namespace (voir mon key=instance).
    L'utilisation de l'__init__ (pour créer l'instance) n'est qu'un exemple: renvoyer l'__init__ (l'instance) à a=* et continuer le code après (getmyname).
    C'est bien sur ridicule et ne fonctionne pas puisque Python attend le retour de l'init pour faire son a=*.

    Citation Envoyé par kango Voir le message
    En revanche tu peux arriver à faire quelque chose si la variable 'a' est associée à une classe que tu contrôles:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    class Toto(object):
        pass
    t = Toto()
    t.a = varname()
    Le code ne correspond pas à ce que je recherche mais s'approche d'une factory.
    C'est sans doute de ce coté que je dois rechercher mais, comme dirait wiztricks, je n'arrive qu'a sortir du code capillo-tractée.

    Je vais continuer dans ce sens.

    Merci

  5. #5
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Et wiztricks à poster entre temps (il ne me manque plus que dividee et un 'arrête les hacks' )

    Eu..? C'est le namespace locals() qui est en lecture seule, pas le globals() Non ?
    J'essaie de lire celui ci donc pas de problème.

    C'est quoi cette histoire de mocker ? (Désolé pour mon manque de vocabulaire)

    Ok pour la note (j'ai assez fais d'expériences dessus )

    Merci

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 356
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 356
    Points : 36 884
    Points
    36 884
    Par défaut
    Citation Envoyé par PauseKawa Voir le message
    Eu..? C'est le namespace locals() qui est en lecture seule, pas le globals() Non ?
    J'essaie de lire celui ci donc pas de problème.
    Yeap.
    Il s'agit en gros de changer le comportement de 'a = b' i.e. l'opération d'assignation ou de mise à jour d'une variable dans le dict du module qui se cache derrière "globals()" pour avoir un contrôle de ce qu'il s'y passe.

    Comme c'est un "dict" on pourrait imaginer le remplacer par un truc qui soit un dict "amélioré"... mais il ne se laisse par remplacer si facilement.
    - W

  7. #7
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Houla ! Cela me semble bien hasardeux avec mon niveau. J'ai bien tenté, il y a quelques temps, ce genre de manipulations avec la customisation des imports mais cela n'est pour moi qu'a titre expérimental.
    Je retiens l'idée pour mes weekend pluvieux

    J'aurais plus pensé à une vérification du namespace externe.
    L'__init__ lance une classe externe et lui donne l'instance (self).
    La classe externe (thread ?) regarde dans le namespace la présence de l'instance.
    Lorsque il trouve l'instance il lance l'instance.getmyname()
    Par contre cela me parait moche.

    Merci

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 356
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 356
    Points : 36 884
    Points
    36 884
    Par défaut
    Salut,

    La vraie question est qu'en dehors de réaliser une fonction bizarre, je n'ai toujours pas compris l'intérêt de ce que tu cherchais à faire.
    Il ne s'agit pas du "quoi": je pense avoir compris que tu essayais d'espionner les changements dans globals() ou de récupérer les variables qui référencent un objet particulier.
    La question est "pourquoi", i.e. une fois cette information obtenue que projettes-tu d'en faire?
    - W

  9. #9
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Bonjour

    En fait j'essaie de trouver une façon 'élégante' de me passer d'inspect et autre.

    Pour le moment je n'ai trouvé qu'une solution assez moche (et surtout externe) je dois dire:
    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
     
    import threading
     
    class verif_instance(threading.Thread):
        def __init__(self, instance):
            threading.Thread.__init__(self)
            self.verifinstance = instance
            self._stopevent = threading.Event()
     
        def run(self):
            while not self._stopevent.isSet():
                for keys in (keys for keys, values in globals().items() if values == self.verifinstance):
                    self.verifinstance.getmyname(keys)
                    self._stopevent.set()	
     
    class varname(object):
        def __init__(self):
            self._name=None
            verif = verif_instance(self)
            verif.start()
     
        def getmyname(self, myname):
            self._name=myname
     
        def getname(self):
            return self._name
     
    a=varname()
    print "Nom de l'instance:", a.getname()

    Toujours dans la recherche d'alternatives comme tu le remarque. Mais bon, cela me permets d'évoluer

    Merci

  10. #10
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 356
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 356
    Points : 36 884
    Points
    36 884
    Par défaut
    re-Salut,
    Si on regarde le truc côté fonctionnel, ce qui est important est:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    a=varname()  # creation de l'entrée et de l'instance
    print "Nom de l'instance:", a.getname()  # l'instance montre ou elle a été référéncée.
    Question: quelle importance de trouver l'entrée avant l'appel a a.getname et éventuellement la récupération de l'attribut "_name"?

    Eventuellement, __init__ peut éventuellement sauvegarder le module appelant - c'est ce globals là qu'il faudra regarder -... Mais tu pourrais initialiser "_name" plus tard, ce qui évite de passer par un thread.
    Est-ce que ce que je raconte est clair?
    - W

  11. #11
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Bonsoir,

    Le but de base est de remplacer les class variables tkinter par un objet Python et ce afin d'éviter les plantages avec les threads (oui, cela remonte à loin. Mais j'ai mon temps, puisque je fais cela pour le plaisir, et je reprend le code lors de mes congés ).
    Ici ce qui m'intéresse, dans le cadre ou j'utilise soit a=moninstance() ou maclass(name=a), est d'écrire dans le globals() (voir le code de la class Variable) soit name et s'il n'est pas spécifié le a=*.
    D'où self._name qui est utilisé pour une inscription de self._name:instance dans les globals(): soit name, soit la key de l'instance.
    C'est là que de savoir quel nom occupe l'instance dans le namespace prend son importance.

    Dans cette situation impossible d'initialiser _name plus tard: Et le callback ?

    Pour ce qui est de savoir si 'ce que je raconte est clair' pour moi j'ai un doute. Ai je bien compris ?

    Merci

  12. #12
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 356
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 356
    Points : 36 884
    Points
    36 884
    Par défaut
    Salut,
    Citation Envoyé par PauseKawa Voir le message
    Dans cette situation impossible d'initialiser _name plus tard: Et le callback ?
    Pour ce qui est de savoir si 'ce que je raconte est clair' pour moi j'ai un doute. Ai je bien compris ?
    Je ne vois pas trop la relation entre callback et self.name qui pourrait être "property".

    creation de l'instance: self._name = None
    quiconque utilise 'name' y accède via self.name i.e.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    @property
    def name(self):
        if self._name is None:
             on cherche la variable dans "globals"
        return self._name
    Pourquoi les callbacks devraient l'utiliser différement?
    - W
    PS: Nous avons 1 pourquoi:
    1 - accès aux variables des structures TK via des threads
    Il en manque 4
    En quoi cela permettra de pallier la non ré-entrance de la bibliothèque?

  13. #13
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Bonsoir,

    Citation Envoyé par wiztricks Voir le message
    PS: Nous avons 1 pourquoi:
    1 - accès aux variables des structures TK via des threads
    Il en manque 4
    Que nenni: Remplacer la class Variable Tk qui utilise la variables Tk et dont le wrapper ne rafraichi par les valeurs assez vite (retourne None) dans le cadre de threads rapides.

    Pour le moment je ne fais que des tests de base mais voici ce que cela donnerait (en gros et rapidement).

    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
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    #!/usr/bin/env python
    # -*- coding: UTF-8 -*-
    #
    # class varclass for jlg_47
    # http://www.developpez.net/forums/d915461/autres-langages/python-zope/general-python/crash-aleatoire-thread/
    # Based on Tkinter variable class
    import threading
     
    class verif_instance(threading.Thread):
        def __init__(self, instance):
            threading.Thread.__init__(self)
            self.verifinstance = instance
            self._stopevent = threading.Event()
     
        def run(self):
            index=0
            while not self._stopevent.isSet():
                for keys in (keys for keys, values in globals().items() if values == self.verifinstance):
                    self.verifinstance.getmyname(keys)
                    self._stopevent.set()
                index += 1
                if index == 10: self._stopevent.set()
     
    class varclass(object):
        _default = ""
        def __init__(self, master=None, value=None, name=None, trace=None, mode=None):
            if not master:
                master = self
            self._master = master
            if value is not None:
                self._value=value
            else:
                self._value=self._default
            self._type=type(self._value)
            if trace:
                self._trace=trace
            else:
                self._trace=None
            if mode:
                self._mode=mode
            else:
                self._mode=None
            self._oldmode=None
            self._oldtrace=None
            self._name=None
            if name:
                self._name = name
                globals()[self._name] = self
            else:
                verif = verif_instance(self)
                verif.start()
     
        def getmyname(self, myname):
            self._name=myname
            globals()[self._name] = self
     
        def __str__(self):
            return str(self._name)
     
        def set(self, value):
            self._value=value
            if self._trace is not None and (self._mode == 'u' or self._mode == 'w'):
                self.savetrace()
                self._oldtrace()
            elif self._oldtrace is not None:
                self.restauretrace()
     
        def get(self):
            if self._trace is not None and (self._mode == 'u' or self._mode == 'r'):
                self.savetrace()
                self._oldtrace()
            elif self._oldtrace is not None:
                self.restauretrace()
            return self._value
     
        def trace_variable(self, mode, callback):
            self._mode=mode
            self._trace=callback
     
        trace = trace_variable
     
        def trace_vdelete(self):
            self._mode=None
            self._trace=None
     
        def trace_vinfo(self):
            return self._mode, self._trace
     
        def varinfo(self):
            # Return the tuple (Master, Name, Value, Type, Trace callback, Trace mode).
            return self._master, self._name, self._value, self._type, self._trace, self._mode
     
        # TODO For callback recursion
        def restauretrace(self):
            self._trace=self._oldtrace
            self._mode=self._oldmode
            self._oldtrace=None
            self._oldmode=None
     
        def savetrace(self):
            self._oldtrace=self._trace
            self._oldmode=self._mode
            self._trace=None
            self._mode=None
     
        def type(self):
            return self._type
     
        # In work
     
        def __eq__(self, other):
            return self.__class__.__name__ == other.__class__.__name__ and self._name == other._name
     
    def test():
        print('Class test --------------------------------------------------------')
        print('Set a=varclass()')
        a=varclass()
        # Default value = ""
        print('Value of a variable after a a=varclass():', a.get())
        # Set a value
        a.set(10)
        print('-------------------------------------------------------------------')
        # Get the value
        print('Value after a a.set():', a.get())
        print('-------------------------------------------------------------------')
        print('Trace test:')
        # trace value
        def callback():
            # Please, don't use multiples get()/set() whith callback
            print('a in callback:', a.get())
            # a.set(30)
        a.trace('u', callback)
        a.set(20)
        print('a after callback:', a.get())
        print('-------------------------------------------------------------------')
        # Callback informations
        print('Callback informations:', a.trace_vinfo())
        print('-------------------------------------------------------------------')
        print('Name test:')
        # Name
        varclass(name='b', value=10)
        print("varclass(name='b', value=10):", 'b name:', b)
        print('-------------------------------------------------------------------')
        # Variable informations
        print('Variable informations:')
        # print('dir(var):', dir(b))
        print('var.varinfo():', b.varinfo())
        print('var.type():', b.type())
        print('-------------------------------------------------------------------')
        # Delete callback
        a.trace_vdelete()
        print('a callback after deletion:', a.trace_vinfo())
        print('-------------------------------------------------------------------')
        # globals/locals
        print('globals()/locals() test:')
        def testglobals():
            varclass(name='c')
            c.set('A')
            print('c in locals():', c.get())
     
        testglobals()
        print('c in globals():', c.get())
     
    if __name__ == "__main__":
        test()
    Merci

    Edit: Et dans le cas d'un thread je risque d'avoir un None (je n'ai pas gérer l'erreur dans le code plus haut). Retour à la case départ. Comment faire autre chose que inspect ou sys ?

  14. #14
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 356
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 356
    Points : 36 884
    Points
    36 884
    Par défaut
    Le même sans les threads, car je pense qu'on se comprends pas
    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
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    #!/usr/bin/env python
    # -*- coding: UTF-8 -*-
    #
    # class varclass for jlg_47
    # http://www.developpez.net/forums/d915461/autres-langages/python-zope/general-python/crash-aleatoire-thread/
    # Based on Tkinter variable class
     
    class varclass(object):
        _default = ""
        def __init__(self, master=None, value=None, name=None, trace=None, mode=None):
            if not master:
                master = self
            self._master = master
            if value is not None:
                self._value=value
            else:
                self._value=self._default
            self._type=type(self._value)
            if trace:
                self._trace=trace
            else:
                self._trace=None
            if mode:
                self._mode=mode
            else:
                self._mode=None
            self._oldmode=None
            self._oldtrace=None
            self._name=None
            if name:
                self._name = name
                globals()[self._name] = self
    #        else:
    #            verif = verif_instance(self)
    #            verif.start()
        @property
        def name(self):
            if self._name is None:
                for key, value in globals().items():
                    if value == self:
                        self._name = key
                        globals()[self._name] = self
            return self._name
    #
    #
    #    def getmyname(self, myname):
    #        self._name=myname
    #        globals()[self._name] = self
     
        def __str__(self):
            return str(self.name)
     
        def set(self, value):
            self._value=value
            if self._trace is not None and (self._mode == 'u' or self._mode == 'w'):
                self.savetrace()
                self._oldtrace()
            elif self._oldtrace is not None:
                self.restauretrace()
     
        def get(self):
            if self._trace is not None and (self._mode == 'u' or self._mode == 'r'):
                self.savetrace()
                self._oldtrace()
            elif self._oldtrace is not None:
                self.restauretrace()
            return self._value
     
        def trace_variable(self, mode, callback):
            self._mode=mode
            self._trace=callback
     
        trace = trace_variable
     
        def trace_vdelete(self):
            self._mode=None
            self._trace=None
     
        def trace_vinfo(self):
            return self._mode, self._trace
     
        def varinfo(self):
            # Return the tuple (Master, Name, Value, Type, Trace callback, Trace mode).
            return self._master, self.name, self._value, self._type, self._trace, self._mode
     
        # TODO For callback recursion
        def restauretrace(self):
            self._trace=self._oldtrace
            self._mode=self._oldmode
            self._oldtrace=None
            self._oldmode=None
     
        def savetrace(self):
            self._oldtrace=self._trace
            self._oldmode=self._mode
            self._trace=None
            self._mode=None
     
        def type(self):
            return self._type
     
        # In work
     
        def __eq__(self, other):
            return self.__class__.__name__ == other.__class__.__name__ and self.name == other.name
     
    def test():
        print('Class test --------------------------------------------------------')
        print('Set a=varclass()')
        a=varclass()
        # Default value = ""
        print('Value of a variable after a a=varclass():', a.get())
        # Set a value
        a.set(10)
        print('-------------------------------------------------------------------')
        # Get the value
        print('Value after a a.set():', a.get())
        print('-------------------------------------------------------------------')
        print('Trace test:')
        # trace value
        def callback():
            # Please, don't use multiples get()/set() whith callback
            print('a in callback:', a.get())
            # a.set(30)
        a.trace('u', callback)
        a.set(20)
        print('a after callback:', a.get())
        print('-------------------------------------------------------------------')
        # Callback informations
        print('Callback informations:', a.trace_vinfo())
        print('-------------------------------------------------------------------')
        print('Name test:')
        # Name
        varclass(name='b', value=10)
        print("varclass(name='b', value=10):", 'b name:', b)
        print('-------------------------------------------------------------------')
        # Variable informations
        print('Variable informations:')
        # print('dir(var):', dir(b))
        print('var.varinfo():', b.varinfo())
        print('var.type():', b.type())
        print('-------------------------------------------------------------------')
        # Delete callback
        a.trace_vdelete()
        print('a callback after deletion:', a.trace_vinfo())
        print('-------------------------------------------------------------------')
        # globals/locals
        print('globals()/locals() test:')
        def testglobals():
            varclass(name='c')
            c.set('A')
            print('c in locals():', c.get())
     
        testglobals()
        print('c in globals():', c.get())
     
    if __name__ == "__main__":
        test()

  15. #15
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Bonsoir,

    Citation Envoyé par wiztricks Voir le message
    Le même sans les threads, car je pense qu'on se comprends pas
    Merci pour le code.
    Effectivement c'est une notion qui m'échappe complètement... Et ce n'est pas la première fois que nous en parlons. J'ai déjà fais des recherches dans ce sens.
    Auriez vous un tuto ou un lien 'simple'?

    Bon code

    Ps: Sinon, que pensez vous de l'idée ?

  16. #16
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Bonjour wiztricks,

    En fait le code donné reviens a exécuter une fonction externe à __init__, comme je le fais avec le thread et self.verifinstance.getmyname(keys).
    Mais, contrairement au thread, cela n'est fait qu'a la demande et après l'__init__ self._name reste à None.

    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
    class varclass(object):
        _default = ""
        def __init__(self, master=None, value=None, name=None, trace=None, mode=None):
            self._name=None
            if name:
                self._name = name
                globals()[self._name] = self
     
        @property
        def name(self):
            if self._name is None:
                for key, value in globals().items():
                    if value == self:
                        self._name = key
                        globals()[self._name] = self
            return self._name
     
        def getname(self):
            return (self._name)
     
        def getname1(self):
            return (self.name)
     
    a=varclass()
    varclass(name='b')
     
    print("a avant l'exécution de name", a.getname(), '<<<<<<<<<<<<<<< ici')
    print("b avant l'exécution de name", b.getname())
    print("a après l'exécution de name", a.getname1())
    print("b après l'exécution de name", b.getname1())
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    ("a avant l'execution de name", None, '<<<<<<<<<<<<<<< ici')
    ("b avant l'execution de name", 'b')
    ("a apres l'execution de name", 'a')
    ("b apres l'execution de name", 'b')
    La question reste entière: Comment exécuter self.name juste après l'instanciation.
    L'utilisation d'un thread est bien sur une mauvaise idée.

    @+

    Edit: instanciation et non __init__

  17. #17
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 356
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 356
    Points : 36 884
    Points
    36 884
    Par défaut
    [QUOTE=PauseKawa;5562492] La question reste entière: Comment exécuter self.name juste après l'instanciation.
    L'utilisation d'un thread est bien sur une mauvaise idée.QUOTE]

    Si "Comment exécuter self.name juste après l'instanciation" signifie poser une sorte de callback sur le 'return' du constructeur de l'instance: Y a pas!

    La seule chose possible semble être de l'initialiser "avant" de l'utiliser.
    C'est ce que fait la mécanique "property".

    Je n'aime pas trop les threads par pour l'overhead mais parce qu'elles sont asynchrones: elle démarre lors de l'__init__ mais devra tester la présence de self dans les values du globals pour éviter de passer "avant" le return.
    Et de toutes façons, l'accès à name devra attendre qu'elle soit terminée.
    Autrement dit, on se retrouve encore avec une property dans lequel on fera un wait de la fin du thread.

    Mais, quelque soit la méthode, la question est de savoir en quoi cela va résoudre le problème de synchro TK.
    - W

    threads ou property permettent de l'initialiser après.

  18. #18
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Bonjour,

    Citation Envoyé par wiztricks Voir le message
    Si "Comment exécuter self.name juste après l'instanciation" signifie poser une sorte de callback sur le 'return' du constructeur de l'instance: Y a pas!
    C'est effectivement la question
    Pourquoi être si rectiligne ? L'exemple du thread (que je n'aime pas) montre que cela est possible.
    Il est même possible d'être plus générique et de donner à un thread la condition et le code à exécuter.

    Citation Envoyé par wiztricks Voir le message
    Je n'aime pas trop les threads par pour l'overhead mais parce qu'elles sont asynchrones: elle démarre lors de l'__init__ mais devra tester la présence de self dans les values du globals pour éviter de passer "avant" le return.
    Que dire... Je ne suis pas trop d'accord.
    Le but ici est de trouver une clé dans un dico à partir d'une instance. La chose est faite non ?
    De plus la clé en question n'existe qu'après le 'return' (fin d'execution de l'__init__).
    Je n'aime pas non plus les threads pour le coté asynchrone.

    Citation Envoyé par wiztricks Voir le message
    Mais, quelque soit la méthode, la question est de savoir en quoi cela va résoudre le problème de synchro TK.
    - W

    threads ou property permettent de l'initialiser après.
    La réponse est non (self._name=None et attente de l'exécution de self.name).
    Le problème de la classe Variable Tk c'est justement le retour de None.
    Dans ce cas bien précis la seule solution est d'avoir l'information directement dans __init__, ce qui implique l'utilisation d'inspect ou sys.

    La solution du remplacement de globals (import __builtin__) fonctionne aussi mais cela deviens du supercapillo-tractée par rapport à inspect ou sys.

    Je pense avoir fais le tour des solutions. Merci pour vos réponses.

    Bon code

  19. #19
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Citation Envoyé par PauseKawa Voir le message
    La réponse est non (self._name=None et attente de l'exécution de self.name).
    Le problème de la classe Variable Tk c'est justement le retour de None.
    Dans ce cas bien précis la seule solution est d'avoir l'information directement dans __init__, ce qui implique l'utilisation d'inspect ou sys.
    Erreur en faveur de la banque.
    Avec la classe Variable Tk c'est le retour d'une valeur None, alors que ce ne devrais pas être la cas, le problème.
    Non pas une erreur de nom.
    C'est à tester en fait.

    @+

  20. #20
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Bonsoir,

    J'avais quelque peut laisser la question de coter suite à cette réponse:
    Citation Envoyé par wiztricks Voir le message
    Si "Comment exécuter self.name juste après l'instanciation" signifie poser une sorte de callback sur le 'return' du constructeur de l'instance: Y a pas!
    Le code était donc en instance comme ceci:
    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
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    #!/usr/bin/env python
    # -*- coding: UTF-8 -*-
    #
    #
    import traceback
    import sys
     
    class IndexStorage():
        """Generic storage class"""
        varnum = 0
     
    class VarClass(object):
    # Class Varclass
    # Test sys/traceback code inspection
    # http://www.developpez.net/forums/d1023748/autres-langages/python-zope/general-python/recuperer-nom-variable-fonction-classe/
    # options:
    # master: parent Widget
    # value: Instance value (Variable or object)
    # name: Instance name in globals() namespace
    # trace: Callback function/class
    # mode: Callback mode (w/r/u)
    # Methods:
    # set(value)
    # get()
    # trace_variable(mode, callback) / trace(mode, callback)
    # trace_vdelete() Delete callback
    # trace_vinfo() Return callback informations
    # varinfo() Retrun instance informations
    # type() Return the type
     
        _default = ""
     
        def __init__(self, master=None, value=None, name=None, trace=None, mode=None):
            if not master:
                master = self
            self._master = master
            if value is not None:
                self._value=value
            else:
                self._value=self._default
            self._type=type(self._value)
            if trace:
                self._trace=trace
            else:
                self._trace=None
            if mode:
                self._mode=mode
            else:
                self._mode=None
            if name:
                self._name = name
            else:
                try:
                    _longname = traceback.extract_stack(limit=2)[0][3].split('=')[0].strip()
                    _shortname = _longname.split('.').pop()
                    if '()' in _shortname:
                        self._noname()
                    else:
                        self._name = _shortname
                except:
                    self._noname()
            globals()[self._name] = self
     
        def _noname(self):
            self._name = 'PY_VAR' + repr(IndexStorage.varnum)
            IndexStorage.varnum += 1
     
        def __str__(self):
            return self._name
     
        def set(self, value):
            self._value=value
            if self._trace is not None and (self._mode == 'u' or self._mode == 'w') and sys._getframe().f_back.f_code.co_name != self._trace.__name__:
                self._trace()
     
        def get(self):
            if self._trace is not None and (self._mode == 'u' or self._mode == 'r') and sys._getframe().f_back.f_code.co_name != self._trace.__name__:
                self._trace()
            return self._value
     
        def trace_variable(self, mode, callback):
            self._mode=mode
            self._trace=callback
     
        trace = trace_variable
     
        def trace_vdelete(self):
            self._mode=None
            self._trace=None
     
        def trace_vinfo(self):
            return self._mode, self._trace
    #
        def trace_value(self, valuetrace, callback):
            self._valuetrace=callback
     
        tracev = trace_value
     
        def trace_valdelete(self):
            self._tracev=None
     
        def trace_valinfo(self):
            return self._valuetrace, self._trace
    #
        def varinfo(self):
            # Return the tuple (Master, Name, Value, Type, Trace callback, Trace mode)
            return self._master, self._name, self._value, self._type, self._trace, self._mode
     
        def type(self):
            return self._type
     
    def test():
        print('Class test --------------------------------------------------------')
        print('Set a=VarClass()')
        a=VarClass()
        # Default value = ""
        print('a value after a=VarClass():', a.get())
        # Set a value
        a.set(10)
        print('-------------------------------------------------------------------')
        # Get the value
        print('Value after a a.set(10):', a.get())
        print('-------------------------------------------------------------------')
        print('Trace test:')
     
        def callback():
            print('a in callback:', a.get())
            print('a.set(30) in callback')
            a.set(30)
     
        a.trace('u', callback)
        a.set(20)
        # Callback informations
        print('Callback informations:', a.trace_vinfo())
        # Delete callback
        a.trace_vdelete()
        print('a.trace_vinfo() after callback deletion:', a.trace_vinfo())
        print('a after callback:', a.get())
        print('-------------------------------------------------------------------')
        VarClass(name='b', value=10)
        # Variable informations
        print('Variable informations:')
        print('var.varinfo():', b.varinfo())
        print('var.type():', b.type())
        print('-------------------------------------------------------------------')
        print('globals()/locals() test:')
     
        def testglobals():
            VarClass(name='c')
            c.set('A')
            print('c in locals():', c.get(), c)
     
        testglobals()
        print('c in globals():', c.get(), c)
        print('-------------------------------------------------------------------')
        print('Name test:')
        print('d=VarClass()')
        d=VarClass()
        print('d name:', d.varinfo()[1])
        VarClass(name='e')
        print("VarClass(name='e'):", e.varinfo()[1])
        VarClass()
        print('VarClass():', globals()['PY_VAR0'])
        print('-------------------------------------------------------------------')
     
    if __name__ == "__main__":
        test()
    Toujours donc dans les inspect et autres traceback...
    Toutefois certaines discutions sur le forum d'hier mon donner l'envie d'y jeter un œil, surtout à cette impossibilité de faire un callback sur le return d' __init__.
    Voici une morceau de code, à titre d'expérimentation personnelle, qui fonctionne partiellement (ne prend pas en compte c=a par exemple):
    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
    import sys
     
    class FuncCapture(object):
        def __init__(self):
            self._exitflag = 0
     
        def start(self, fctotrace, clb, clstotrc):
            self._classtotrace = clstotrc
            self._clb = clb
            self._fctotrace = fctotrace
            self._olddico = {}
            for key, value in globals().iteritems():
                self._olddico[key] = value
            sys.setprofile(self._TraceIt)
     
        def _TraceIt(self, frame, event, arg):
            if event == 'call' and self._exitflag == 1:
                self._ExecCB()
                self._exitflag = 0
            elif event == 'return' and frame.f_code.co_name == self._fctotrace:
                self._exitflag = 1
     
        def _ExecCB(self):
            sys.setprofile(None)
            for key in [key for key in globals().keys() if key not in self._olddico.keys()]:
                if '<__main__.' + self._classtotrace +  ' object at' in str(globals()[key]):
                    exec(key + '.' + self._clb + '()')
     
    def initrace(fcinstance, ftotrace, clbk, clstotrc):
        def lauchfc(func):
            def execcode(*args, **kwargs):
                fcinstance.start(ftotrace, clbk, clstotrc)
                _retour = func(*args, **kwargs)
                return _retour
            return execcode
        return lauchfc
     
    class Foo(object):
        fc = FuncCapture()
        @initrace(fc, '__init__', '_Callback', 'Foo')
        def __init__(self):
            self._name = None
     
        def _Callback(self): # options
            for k, v in globals().iteritems():
                if v == self:
                    self._name = k
     
        def GetName(self):
            return self._name
     
    if __name__ == '__main__':
        a=Foo()
        b=Foo()
        print a.GetName()
        print b.GetName()
    La class FuncCapture gère l'appel du callback.
    Le décorateur initrace lui lance le suivit de la fonction de pars le pré trainement et donne à FuncCapture les information utiles (nom de la fonction à tracer (ici __init__), nom de la fonction de callback et le nom de la classe. Sans doute à revoir).
    _TraceIt trace les events et après le return de la fonction tracée stoppe la surveillance et lance la fonction de callback.
    A chaque __init__ le décorateur relance la procédure.
    C'est sans doute moche, et surtout perfectible, mais la fonction _Callback est bien exécutée juste après le return.

    Je répète : A prendre pour de l'expérimental (et complètement ouvert à la critique).

    @+

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Executer du code aprés changement
    Par docjo dans le forum VBA Access
    Réponses: 4
    Dernier message: 18/08/2009, 16h23
  2. Executer du code vba apres un publipostage
    Par xcbilx dans le forum VBA Word
    Réponses: 6
    Dernier message: 10/04/2008, 00h53
  3. Réponses: 2
    Dernier message: 06/04/2006, 10h35
  4. Réponses: 4
    Dernier message: 15/12/2005, 18h28
  5. [C#]Comment executer du code qui se trouve dans une string ?
    Par freddyboy dans le forum Windows Forms
    Réponses: 4
    Dernier message: 28/02/2005, 16h31

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo