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 :

Placer un objet dans global au sein d'une fonction


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 Placer un objet dans global au sein d'une fonction
    Bonjour,

    Est il possible de dire qu'un objet est global au sein d'une fonction ?

    Je m'explique, j'ai :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    def unefonc():
        ....
     
    def  uneautre():
        a=unefonc()
    Comment dire au sein de unefonc() que a est dans global ?
    Est ce possible ?

    Merci d'avance
    Merci d'utiliser le forum pour les questions techniques.

  2. #2
    Membre habitué
    Inscrit en
    Avril 2010
    Messages
    99
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Avril 2010
    Messages : 99
    Points : 143
    Points
    143
    Par défaut
    Bonjour,

    Je suis désolé mais j'ai pas compris ce que tu cherchais à faire.

    Tu dis que tu veux que a soit une variable globale dans la fonction unefonc mais dans ton exemple, tu t'en sers dans uneautre.

    Pourrais-tu être un peu plus précis s'il te plaît ?

  3. #3
    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 Biribibi,

    A vrais dire, et pour donner le vrais code, j'ai la classe suivante :

    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
    #!/usr/bin/env python
    # -*- coding: UTF-8 -*-
    #
    # class myvar for jlg_47
    # http://www.developpez.net/forums/d915461/autres-langages/python-zope/general-python/crash-aleatoire-thread/
    # Based on Tkinter variable class
    class myvar:
        _default = ""
        def __init__(self, master=None, value=None, name=None, trace=None, mode=None, visible=None):
            if not master:
                master = self
            self._master = master
            if name:
                self._name = name
            else:
                self._name = None
            if value is not None:
                self._value=value
            else:
                self._value=self._default
            if trace:
                self._trace=trace
            else:
                self._trace=None
            if mode:
                self._mode=mode
            else:
                self._mode=None
            self._oldmode=None
            self._oldtrace=None
     
        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 "Master", self._master, "Name", self._name, "Value", str(self._value), "Trace callback", self._trace, "Trace mode", 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
     
    if __name__ == "__main__":
        a=myvar()
     
        # Default value = ""
        print a.get()
        # Set a value
        a.set(10)
        # Get the value
        print a.get()
     
        # 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'
        print a.get()
     
        # Callback informations
        print 'Callback informations', a.trace_vinfo()
     
        # Name
        b=myvar(name='b')
        print 'b name', b
     
        # Variable informations
        print 'Variable informations'
        dir(b)
        print b.varinfo()
     
        # Delete callback
        a.trace_vdelete()
        print a.trace_vinfo()
    Je souhaite savoir s'il est possible de dire que si visible=True dans le cadre de a=myvar(visible=True) a est créé dans le global, même s'il n'y est pas.
    A vrais dire je cherche a savoir s'il est possible de faire
    global a
    a=myvar()
    Mais dans myvar...

    Je sais que c'est tordu et autant placer a=myvar() directement mais c'est pour simuler la class variable Tk.

    @+
    Merci d'utiliser le forum pour les questions techniques.

  4. #4
    Membre habitué
    Inscrit en
    Avril 2010
    Messages
    99
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Avril 2010
    Messages : 99
    Points : 143
    Points
    143
    Par défaut
    Je crois avoir compris ton problème.
    A mon avis, c'est impossible.
    Dans l'expression a = myVar(), même si a et myVar sont dans la expression, il n'y a pas de rapport entre a et myVar() en dehors du fait qu'on va assigner à la variable a et le résultat de myVar().
    La fonction myVar n'a aucune information sur la variable a (dans le sens où elle ne fait que renvoyer une valeur et elle ne sait pas ce que le programme va en faire), alors je ne vois pas en quoi elle pourrait changer sa portée.

    Bon dans tous les cas, si c'était possible, je trouverais ça super moche et source de bugs. Ca me fait penser aux super-features que nous propose Perl à chaque version (ce n'est pas un compliment).

  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
    Bonjour,

    Citation Envoyé par Biribibi Voir le message
    A mon avis, c'est impossible.
    Il me semble aussi. J'avais espéré une Zenitude de plus avec Python pour passer outre
    Mais bon, je vais bien trouver un moyen de remplacer le global _varnum de Tkinter.
    Je laisse ouvert au cas ou.
    Merci de ta réponse.

    @+
    Merci d'utiliser le forum pour les questions techniques.

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 277
    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 277
    Points : 36 762
    Points
    36 762
    Par défaut
    Salut
    Je ne comprends pas trop mais pourquoi ne pas faire:
    a = MyVar(name='a') qui retourne une nouvelle instance de MyVar appelée 'a' si une telle instance n'existe pas encore, l'instance de nommée 'a'?
    - W
    PS: J'avais fait des POST là dessus non?
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  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
    Bonsoir wiztricks,

    Citation Envoyé par PauseKawa Voir le message
    # Name
    b=myvar(name='b')
    Après je bloque...

    J'ai bien fais des recherches sur le forum (et les moteurs de recherche) mais je n'ai rien trouvé dans le sens de ma question. Cela viens sans doute de mon manque de bases/vocabulaire (toujours pas lu les tutos... . Tout en terminal/gedit/edit+++ .... Mais c'est Zen Python )

    Si tu as encore en mémoire un post ou tu parle du sujet est il possible de l'avoir ? Je regarde de mon coté bien sur.

    Merci d'avance.
    Merci d'utiliser le forum pour les questions techniques.

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 277
    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 277
    Points : 36 762
    Points
    36 762
    Par défaut
    Salut PauseKawa,

    En gros, ça ressemble à çà:

    Code Python : 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
    class _MyVar():
        _registry=dict()  # pour y coller les instances
     
        def __init__(self, name=None):
             if name:
                   assert not name in self._registry # pas encore dans...
                   self._registry[name] = self # il y est
             self._name = name
     
        def __call__(self, name):
             if name in self._registry:
                   return self._registry[name]
             myvar = _MyVar(name=name) # il n'existe pas
             return myvar
     
        def __str__(self):
             return self._name
     
    MyVar = _MyVar()
     
     
    def test():
        '''
        >>> a = MyVar(name='a')
        >>> b = MyVar(name='b')
        >>> str(a) == 'a'
        True
        >>> c = MyVar(name='a')
        >>> id(c) == id(a)
        True
        '''
     
    if __name__ == '__main__':
        import doctest
        doctest.testmod()

    En faisant passer la construction des instances de MyVar par __call__, 'on contrôle' leur création. En POO, c'est une 'factory'.

    La '_registry' est une variable de classe (et non d'instance). C'est ce qui est à la base d'un autre 'truc' POO qui s'appelle 'Singleton'.

    Je préfère y accéder via self plutôt que par le nom de la classe.
    Mais çà ne présente pas plus de difficultés que le micmac locals/globals dans les fonctions: les variables 'globales' sont accessible 'en lecture', mais à défaut de pouvoir changer le contenant, on peut modifier le contenu...
    Bon courage
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  9. #9
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Points : 1 384
    Points
    1 384
    Par défaut
    Bonsoir,

    On peut faire la même chose que ce que fait wiztricks en passant par une metaclasse:
    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
    class MetaFlyWeight(type):
        def __init__(cls, classname, bases, attrs):
            super(MetaFlyWeight, cls).__init__(classname, bases, attrs)
            cls._registry = {}
     
        def __call__(cls, name):
            if name not in cls._registry:
                cls._registry[name] = super(MetaFlyWeight, cls).__call__(name)
            return cls._registry[name]
     
    class MyVar(object):
        __metaclass__ = MetaFlyWeight
     
        def __init__(self, name):
            self._name = name
     
        def __str__(self):
            return self._name
    MetaFlyWeight.__init__ est appelé lors de l'initialisation de la classe MyVar, et y ajoute un attribut de classe (_registry).
    MetaFlyWeight.__call__ est appelé lors de la création d'une instance de MyVar. Cela permet une personnalisation de la création d'instances plus poussée qu'en redéfinissant MyVar.__new__.

    J'ai donné ce nom à la metaclasse car cela me rappelle le design pattern "poids mouche".

    C'est un peu plus complexe (enfin, pas tant que ça) mais cela a quelques avantages; on peut le voir comme une refactorisation du code de wiztricks, où on a séparé les fonctionnalités de création d'instances (factory) de celles de la classe elle-même. La méthode __call__ de la class MyVar est aussi maintenant utilisable, au besoin.

    Il y a aussi une différence au niveau de l'héritage: toute classe héritant de MyVar héritera aussi de sa métaclasse et aura un dictionnaire d'instances (_registry) qui lui est propre.

    [EDIT:] petite correction/simplification du code

  10. #10
    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,

    Super, en deux réponses vous venez de solder mes RTT.
    C'est pour moi le minimum requit pour les comprendre...

    Bon... Je me lance et je reviens voir si j'ai bien compris.

    Merci de vos réponses

    @+

    Edit :

    Pour ma défense je dirais que j'avais penser au stockage dans une liste ( _registry=dict()) mais que je ne savais pas quoi en faire
    Merci d'utiliser le forum pour les questions techniques.

  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
    Bonjour,

    Merci pour les recherches. Je vais approfondir tout cela.

    Par contre pour une réponse plus simple c'est wiztricks qui avais le mots magique... =dict(). globals() et locals() sont des dico. Donc :

    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
    #!/usr/bin/env python
    # -*- coding: UTF-8 -*-
    #
    # class myvar for jlg_47
    # http://www.developpez.net/forums/d915461/autres-langages/python-zope/general-python/crash-aleatoire-thread/
    # Based on Tkinter variable class
    class myvar:
        _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
            if trace:
                self._trace=trace
            else:
                self._trace=None
            if mode:
                self._mode=mode
            else:
                self._mode=None
            self._oldmode=None
            self._oldtrace=None
            if name:
                self._name = name
                globals()[self._name] = self
    
        # def __call__(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 "Master", self._master, "Name", self._name, "Value", str(self._value), "Trace callback", self._trace, "Trace mode", 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
     
    if __name__ == "__main__":
        a=myvar()
     
        # Default value = ""
        print a.get()
        # Set a value
        a.set(10)
        # Get the value
        print a.get()
     
        # trace value
        def callback():
            # Please, don't use multiples get()/set() whith callback
            print 'a in callback', a.get()
            # a.set(30)
            # Named variables is in globals : globals()["b"] = myvar(name='b')
            b=myvar(name='b')
        a.trace('u', callback)
        a.set(20)
        print 'a after callback'
        print a.get()
     
        # Callback informations
        print 'Callback informations', a.trace_vinfo()
     
        # Name
        print 'b name', b
     
        # Variable informations
        print 'Variable informations'
        dir(b)
        print b.varinfo()
     
        # Delete callback
        a.trace_vdelete()
        print a.trace_vinfo()
    
        # Named variables (b) in globals
        print globals()
    Bon, j'y retourne

    @+
    Merci d'utiliser le forum pour les questions techniques.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 28/01/2014, 01h41
  2. Requête au sein d'une fonction contenant une variable
    Par hel22 dans le forum MS SQL Server
    Réponses: 5
    Dernier message: 11/07/2007, 13h03
  3. Réponses: 15
    Dernier message: 22/03/2007, 02h35
  4. [Swing][JList] Placer un Objet dans une liste
    Par Invité dans le forum Composants
    Réponses: 1
    Dernier message: 17/02/2006, 10h31
  5. Ecrire dans un tableau html depuis une fonction js ?
    Par botanica dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 05/10/2005, 12h48

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