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 :

M�taclasses vs d�corateur


Sujet :

Python

  1. #1
    Membre confirm� Avatar de fma38
    Profil pro
    Inscrit en
    Mai 2013
    Messages
    119
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2013
    Messages : 119
    Par d�faut M�taclasses vs d�corateur
    Bonjour,

    Je suis en train de tester 2 solutions pour faire un Singleton : par m�taclasse, et par d�corateur.

    Si la m�taclasse fonctionne bien, j'ai un truc bizarre avec le d�corateur :

    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
    def singleton(cls):
        instances = {}
        def getinstance():
            if cls not in instances:
                instances[cls] = cls()
            return instances[cls]
        return getinstance
     
    @singleton
    class MyClass(object):
        def __init__(self):
            super(MyClass, self).__init__()
            self.a = 1
     
    MyClass()
    car j'obtiens :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    Traceback (most recent call last):
      File "deco.py", line 17, in <module>
        MyClass()
      File "deco.py", line 5, in getinstance
        instances[cls] = cls()
      File "deco.py", line 13, in __init__
        super(MyClass, self).__init__()
    TypeError: must be type, not function
    Quelqu'un peut-il m'expliquer ce qui se passe, exactement ? Je n'arrive pas � suivre le cheminement de python lors de la cr�ation/initialisation de la classe... J'imagine qu'une fois compris �a, la r�ponse coule se source

    Merci d'avance.

  2. #2
    Expert �minent
    Homme Profil pro
    Architecte technique retrait�
    Inscrit en
    Juin 2008
    Messages
    21 774
    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 774
    Par d�faut
    Salut,
    Citation Envoy� par fma38 Voir le message
    Quelqu'un peut-il m'expliquer ce qui se passe, exactement ?
    Le message d'erreur est explicite: vous remplacez une classe par une fonction et super n'aime pas.
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Expert confirm�
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 104
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activit� : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 104
    Par d�faut
    On est bien d'accord sur le fait que tu veux un singleton pour n'avoir � cr�er qu'une seule instance ?

    C'est rare ce genre d'utilisation, j'aimerais bien savoir pour quel besoin exactement.

    Bref, le singleton le plus pythonique (que je connaisse) est celui-ci

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    class Singleton(object):
        def __new__(cls, *args, **kwargs):
            if '_inst' not in vars(cls):
                cls._inst = type.__new__(cls, *args, **kwargs)
            return cls._inst
    Source : J�rgen Hermann

    Bonne continuation...

  4. #4
    Membre confirm� Avatar de fma38
    Profil pro
    Inscrit en
    Mai 2013
    Messages
    119
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2013
    Messages : 119
    Par d�faut
    Citation Envoy� par wiztricks Voir le message
    Le message d'erreur est explicite: vous remplacez une classe par une fonction et super n'aime pas.
    Pourquoi 'je emplace' ? C'est l� o� je ne suis pas s�r de piger. Certes, le d�corateur encapsule la classe dans une fonction, mais cela reste une classe, non ? O� alors cela veut dire que m�me les appel depuis l'int�rieur voit la fonction au lieu de la classe ?

  5. #5
    Membre confirm� Avatar de fma38
    Profil pro
    Inscrit en
    Mai 2013
    Messages
    119
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2013
    Messages : 119
    Par d�faut
    Citation Envoy� par fred1599 Voir le message
    On est bien d'accord sur le fait que tu veux un singleton pour n'avoir � cr�er qu'une seule instance ?
    Yep, c'est �a.

    C'est rare ce genre d'utilisation, j'aimerais bien savoir pour quel besoin exactement.
    J'ai 2-3 objets qui sont des services globaux dont je veux disposer sans avoir besoin de les passer en param�tre � tout va. Genre le logger.

    Bref, le singleton le plus pythonique (que je connaisse) est celui-ci

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    class Singleton(object):
        def __new__(cls, *args, **kwargs):
            if '_inst' not in vars(cls):
                cls._inst = type.__new__(cls, *args, **kwargs)
            return cls._inst
    Source : J�rgen Hermann
    Y'a effectivement plein de fa�ons de faire : je le fais aussi via une variable de module. Sinon, au boulot, dans notre gros code, on utilise plut�t des Borgs que des Singleton.

    Mais bon, je ne veux pas rentrer dans le d�bat de l'un ou de l'autre utilisation ; c'�tait juste pour comprendre ce qui se passait avec le d�corateur (pas sp�cifique au Singleton, d'ailleurs).

    Merci.

  6. #6
    Expert �minent
    Homme Profil pro
    Architecte technique retrait�
    Inscrit en
    Juin 2008
    Messages
    21 774
    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 774
    Par d�faut
    Citation Envoy� par fma38 Voir le message
    Pourquoi 'je emplace' ? C'est l� o� je ne suis pas s�r de piger. Certes, le d�corateur encapsule la classe dans une fonction, mais cela reste une classe, non ? O� alors cela veut dire que m�me les appel depuis l'int�rieur voit la fonction au lieu de la classe ?
    C'est pourtant ce que dit le message d'erreur.
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  7. #7
    Expert confirm�
    Avatar de tyrtamos
    Homme Profil pro
    Retrait�
    Inscrit en
    D�cembre 2007
    Messages
    4 486
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes C�te d'Azur)

    Informations professionnelles :
    Activit� : Retrait�

    Informations forums :
    Inscription : D�cembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par d�faut
    Bonjour,

    Oui, super n'a pas l'air de supporter une classe directement issue de object, et je ne suis pas s�r que l'appel de __init__ de object soit n�cessaire.

    Sinon, les solutions du singleton avec d�corateur sont int�ressantes. Voil� comment je le coderais (Python 2.7):

    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
    def singleton(fonc):
        instances = []
        def appelfonc(*args, **kwargs):
            if fonc not in instances:    
                instances.append(fonc)
                return fonc(*args, **kwargs)
            else:
                raise ValueError, ("erreur: tentative 2e instance de " + fonc.__name__)
        return appelfonc
     
    @singleton
    class MyClass(object):
        def __init__(self):
            object.__init__(self)
            self.a = 1
     
    x = MyClass()
    y = MyClass() #<=== erreur: tentative de création d'une 2ème instance
    Le "raise" sugg�re que l'appelant g�re l'exception.

    On peut aussi vouloir limiter la cr�ation des instances � un certain nombre, par exemple 2 ou 3. Dans ce cas, on peut utiliser un d�corateur qui accepte un param�tre:

    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
    def singleton(max=1):
        instances = [] 
        def _decorateur(fonc):
            def appelfonc(*args, **kwargs):
                if instances.count(fonc)<max:    
                    instances.append(fonc)
                    return fonc(*args, **kwargs)
                else:
                    raise ValueError, ("erreur: tentative 2e instance de " + fonc.__name__)
            return appelfonc
        return _decorateur
     
    @singleton(2)
    class MyClass(object):
        def __init__(self):
            object.__init__(self)
            self.a = 1
     
    x = MyClass()
    y = MyClass()
    z = MyClass() # <=== erreur: tentative de création d'une 3ème instance
    Attention: dans ce d�corateur avec param�tre, il faut toujours mettre les parenth�ses, m�me si on laisse la valeur par d�faut => @singleton().

  8. #8
    Membre confirm� Avatar de fma38
    Profil pro
    Inscrit en
    Mai 2013
    Messages
    119
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2013
    Messages : 119
    Par d�faut
    Citation Envoy� par tyrtamos Voir le message
    Oui, super n'a pas l'air de supporter une classe directement issue de object, et je ne suis pas s�r que l'appel de __init__ de object soit n�cessaire.
    C'est le fait que le premier param�tre soir une fonction et non une classe qui l'emb�te...

    Et si, l'appel � super() est important lorsqu'on h�rite de object ; sans lui, la r�solution des appels lors de l'h�ritage multiple ne suit plus celle du new-style, justement ! Entre autres...

    Sinon, les solutions du singleton avec d�corateur sont int�ressantes. Voil� comment je le coderais (Python 2.7):
    Merci pour ces exemples !

  9. #9
    Expert �minent
    Homme Profil pro
    Architecte technique retrait�
    Inscrit en
    Juin 2008
    Messages
    21 774
    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 774
    Par d�faut
    Salut,
    Citation Envoy� par fma38 Voir le message
    Et si, l'appel � super() est important lorsqu'on h�rite de object ; sans lui, la r�solution des appels lors de l'h�ritage multiple ne suit plus celle du new-style, justement ! Entre autres...
    Quel est le sens d'un singleton dans un h�ritage multiple? voire d'un h�ritage simple? Vous g�rez comment le threading pour garantir l�unicit� de l'instance du Singleton?
    Quels sont les avantages inconv�nient de l'utilisation d'un module (comme singleton) par rapport a des solutions autres?

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  10. #10
    Membre confirm� Avatar de fma38
    Profil pro
    Inscrit en
    Mai 2013
    Messages
    119
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2013
    Messages : 119
    Par d�faut
    Citation Envoy� par wiztricks Voir le message
    Quel est le sens d'un singleton dans un h�ritage multiple? voire d'un h�ritage simple? Vous g�rez comment le threading pour garantir l�unicit� de l'instance du Singleton?
    Ma r�ponse concernant l'appel � super() �tait en fait g�n�rique ; effectivement, dans le cas pr�sent, �a peut se discuter. Mais bon, h�riter de objet et ne pas avoir son comportement n'est � mon avis pas une bonne id�e. C'est un coup � se retrouver face � des trucs bizarres (le probl�me de r�solution de nom n'est sans doute qu'un des probl�mes potentiels...).

    Quant � la gestion en multithreading, je n'y ai jamais �t� confront�, puisque j'utilisais jusqu'� pr�sent uniquement des Borg. Et �a, �a fonctionne tr�s bien.

    Quels sont les avantages inconv�nient de l'utilisation d'un module (comme singleton) par rapport a des solutions autres?
    Jamais pes� le pour et le contre, � vrai dire. L'utilisation de la variable de module m'avait �t� sugg�r� par un formateur python tr�s comp�tent. L� encore, je n'ai jamais pris cette impl�mentation en d�faut, m�me en multithreading !

  11. #11
    Expert confirm�
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 104
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activit� : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 104
    Par d�faut
    L'h�ritage de Singleton n'est pas un cas simple, et comme le dis Wiztrick, chaque sous classe directe ou indirecte recevra une instance distincte. Ce qui en d'autres termes viole la contrainte une seule instance.

    Cette probl�matique peut �tre g�nante et dans ce cas, il serait souhaitable d'utiliser l'idiome Borg.

    Edit: Juste un petit rajout pour parler du choix des motifs Singleton ou Borg, qui tr�s souvent, si on y r�fl�chi bien, n'a pas besoin d'�tre utilis�.

    En python, on peut faire tr�s simple et les �viter en faisant

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    class A(object):
        def __init__(self):
            # blabla
     
    A = A()
    Dans le cas ci-dessus A est la seule instance de sa propre classe.

    Bonne continuation...

  12. #12
    Expert �minent
    Homme Profil pro
    Architecte technique retrait�
    Inscrit en
    Juin 2008
    Messages
    21 774
    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 774
    Par d�faut
    Citation Envoy� par fma38 Voir le message
    Ma r�ponse concernant l'appel � super() �tait en fait g�n�rique ; effectivement, dans le cas pr�sent, �a peut se discuter.
    ...
    Quant � la gestion en multithreading, je n'y ai jamais �t� confront�, puisque j'utilisais jusqu'� pr�sent uniquement des Borg. Et �a, �a fonctionne tr�s bien.
    Un pattern "monostate" (aka. Borg) a d'autres cas d'utilisations que "singleton". Ce sont ces cas d'utilisations qui rendent "glissantes" toutes consid�rations "g�n�riques": super() dans le cas d'un singleton est "a probl�me" que n'aura pas "monostate".

    Jamais pes� le pour et le contre, � vrai dire. L'utilisation de la variable de module m'avait �t� sugg�r� par un formateur python tr�s comp�tent. L� encore, je n'ai jamais pris cette impl�mentation en d�faut, m�me en multithreading !
    Il est vrai que l'informatique ressemble parfois a des recettes de cuisines qu'on se refile d'un forum a l'autre... mais c'est un peu plus complique.
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  13. #13
    Membre confirm� Avatar de fma38
    Profil pro
    Inscrit en
    Mai 2013
    Messages
    119
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2013
    Messages : 119
    Par d�faut
    En fait, je me pose la question de savoir dans quel cas on a r�ellement besoin d'un vrai Singleton ?

  14. #14
    Expert confirm�
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 104
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activit� : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 104
    Par d�faut
    Je n'ai pas r�pondu � cette question le post pr�c�dent ?

  15. #15
    Expert �minent
    Homme Profil pro
    Architecte technique retrait�
    Inscrit en
    Juin 2008
    Messages
    21 774
    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 774
    Par d�faut
    Salut,
    Citation Envoy� par fred1599 Voir le message
    Edit: Juste un petit rajout pour parler du choix des motifs Singleton ou Borg, qui tr�s souvent, si on y r�fl�chi bien, n'a pas besoin d'�tre utilis�.

    En python, on peut faire tr�s simple et les �viter en faisant

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    class A(object):
        def __init__(self):
            # blabla
     
    A = A()
    Dans le cas ci-dessus A est la seule instance de sa propre classe.
    Ah ben si on revient aux variables globales, effectivement, pas la peine de...
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

Discussions similaires

  1. [DisplayTag] D�corateur display tag
    Par newmar dans le forum Taglibs
    R�ponses: 5
    Dernier message: 18/06/2008, 16h19
  2. Utilit� des d�corateurs en JAVA
    Par specsy dans le forum G�n�ral Java
    R�ponses: 5
    Dernier message: 15/04/2008, 17h32
  3. R�ponses: 3
    Dernier message: 07/12/2007, 11h35
  4. [D�corateur] Desassembler des D�corateurs
    Par NiamorH dans le forum Design Patterns
    R�ponses: 3
    Dernier message: 28/10/2007, 09h29

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