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 :

objet passe partout


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert
    Inscrit en
    Août 2010
    Messages
    1 124
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 1 124
    Par défaut objet passe partout
    Bonjour,

    Voici une petite classe dont le but est d’être utilisée comme proxy de n'importe quoi. Son but est de "passer partout", i.e ne pas lever d'erreur lorsqu'elle est utilisée à la place de l'objet attendu.

    Voyez une fonctionnalité que j'aurais oublié, ou une amélioration quelconque ?
    Merci d'avance.

    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
     
    class PassePartout:
        """Universal Proxy Object"""
        _exemple= None
        def __init__(self): pass
        def __getattr__(self,key):
            if key== "__str__": return "PassePartout"
            if key== "__repr__": return "PassePartout"
            return PassePartout()
        def __setattr__(self,key,value): pass
        def __getitem__(self,key):  return PassePartout()
        def __setitem__(self,key,value):
            pass
        def __str__(self):return "PassePartout"
        def __repr__(self):return "PassePartout"
        def __hash__(self):    
            """same hashcode for every instance"""
            if PassePartout._exemple is None:
                PassePartout._exemple= PassePartout()
            return object.__hash__(PassePartout._exemple)
        def __call__(self,*args,**kwargs): return PassePartout()
        def __nonzero__(self,*args,**kwargs): return True
        def __coerce__(self,other):
            this= None
            if other.__class__== float(1.0).__class__: this= 0.0
            if other.__class__== int(1).__class__: this= 0
            return (this,other)

  2. #2
    Membre Expert 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
    Par défaut
    Bonjour VV33D,

    Je ne vois pas trop l'utilité (Un exemple pour me mettre sur la voie ?) mais je me dit que si l'objet est itérable cela risque de durer un moment.

    @+

  3. #3
    Membre très actif
    Avatar de afranck64
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2009
    Messages
    592
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2009
    Messages : 592
    Par défaut
    pourqu'il soit "passe partout" il devra impérativement toujours répondre True à isinstanceof et là...

    Si une string me répond True lorsque je demande un Canvas les carottes pourraient bien cuir.
    Win 10 64 bits / Linux Mint 18, - AMD A6 Quad: Py27 / Py35
    CONTENU D'UNE QUESTION
    Exemples:
    - Configuration (système d'exploitation, version de Python et des bibliothèques utilisées)
    - Code source du morceau de programme où il y a un bogue
    - Ligne de code sur laquelle le bogue apparaît
    - Erreur complète retournée pas l'interpréteur Python
    - Recherche déjà effectuée (FAQ, Tutoriels, ...)
    - Tests déjà effectués

  4. #4
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 738
    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 738
    Par défaut
    Salut

    object est déjà là pour çà (ou plutôt qu'ajoute PassePartout à object qui le rende "intéressant")

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    >>> class A: pass
    ...
    >>> a = A()
    >>> isinstance(a, object)
    True
    >>> a
    <__main__.A object at 0x025BBE90>
    >>> isinstance('bla', object)
    True
    >>>
    Note: je ne dis pas que cela ne sert à rien, juste que je n'ai pas compris à quoi... Je n'ai pas retrouvé un post de Dividee sur un sujet analogue (proxy).

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

  5. #5
    Membre très actif
    Avatar de afranck64
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2009
    Messages
    592
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2009
    Messages : 592
    Par défaut
    Mes pensées étaient plutôt:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    partout = PassePartout()
    isinstance(partout, str) #True
    isinstance(partout, Canvas) #True
    ps:
    isinstanceof isinstance (Ma lecture de java me monte à la tête )
    Win 10 64 bits / Linux Mint 18, - AMD A6 Quad: Py27 / Py35
    CONTENU D'UNE QUESTION
    Exemples:
    - Configuration (système d'exploitation, version de Python et des bibliothèques utilisées)
    - Code source du morceau de programme où il y a un bogue
    - Ligne de code sur laquelle le bogue apparaît
    - Erreur complète retournée pas l'interpréteur Python
    - Recherche déjà effectuée (FAQ, Tutoriels, ...)
    - Tests déjà effectués

  6. #6
    Membre Expert
    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
    Par défaut
    Je ne comprends pas très bien l'usage moi non plus.
    Si c'est un proxy, comment est-il initialisé ? (un proxy renvoie à autre chose).
    Si c'est un "trou noir" (un objet qui retourne toujours lui-même, quel que soit l'opération qu'on lui applique), pourquoi ne pas en faire un singleton ?
    Pourquoi "return PassPartout()" et pas "return self" ?

  7. #7
    Membre très actif
    Avatar de afranck64
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2009
    Messages
    592
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2009
    Messages : 592
    Par défaut
    Citation Envoyé par VV33D Voir le message
    Bonjour,

    Voici une petite classe dont le but est d’être utilisée comme proxy de n'importe quoi. Son but est de "passer partout", i.e ne pas lever d'erreur lorsqu'elle est utilisée à la place de l'objet attendu.
    Pour ma part, il devrait y avoir un scindage:
    - Un proxy:
    une petite classe dont le but est d’être utilisée comme proxy de n'importe quoi.
    - un foure-tout:
    ne pas lever d'erreur lorsqu'elle est utilisée à la place de l'objet attendu
    Les proxys etants déjà Built-In, il reste plus qu'à faire le foure-tout.
    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
    class PassePartout:
        """Universal Proxy Object"""
        _exemple= None
        __class__ = object
        def __init__(self, *args, **kw):    #s'il passe partout, il doit pouvoir tout gober!
            self._nextCount = False
            pass
     
        def __getattr__(self,key):
            if key== "__str__": return "PassePartout"
            if key== "__repr__": return "PassePartout"
            return PassePartout()   #Dans le fond, c'est plutôt bien pensé
     
        def __setattr__(self,key,value):
            pass
     
        def __getitem__(self,key):
            return PassePartout()   #Pareil que plus haut.
     
        def __setitem__(self,key,value):
            pass
     
        def __str__(self):return "PassePartout"
     
        def __repr__(self):return "PassePartout"
     
        def __hash__(self):
            """same hashcode for every instance"""
            if PassePartout._exemple is None:
                PassePartout._exemple= PassePartout()
            return object.__hash__(PassePartout._exemple)
     
        def __call__(self,*args,**kwargs): return PassePartout()
     
        def __nonzero__(self,*args,**kwargs): return True
     
        def __coerce__(self,other):
            this= None
            if other.__class__== float(1.0).__class__: this= 0.0
            if other.__class__== int(1).__class__: this= 0
            return (this,other)
     
        def __len__(self):
            return 1
     
        len = __len__
     
        def __next__(self):
                raise StopIteration
     
        next = __next__
     
        def __iter__(self):
            return iter((self,))
     
        def __instancecheck__(self, instance):
            print "check instance"       #je parviens pas à le faire rouler (py2.7)
            return True
     
        def __subclasscheck__(self, subclass):
            print "check class"    #Lui non plus
            return True
    Win 10 64 bits / Linux Mint 18, - AMD A6 Quad: Py27 / Py35
    CONTENU D'UNE QUESTION
    Exemples:
    - Configuration (système d'exploitation, version de Python et des bibliothèques utilisées)
    - Code source du morceau de programme où il y a un bogue
    - Ligne de code sur laquelle le bogue apparaît
    - Erreur complète retournée pas l'interpréteur Python
    - Recherche déjà effectuée (FAQ, Tutoriels, ...)
    - Tests déjà effectués

  8. #8
    Membre Expert 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
    Par défaut
    Bonjour afranck64,

    Pourquoi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        def __len__(self):
            return 1
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        def __iter__(self):
            return iter((self,))
    Plutôt que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        def __len__(self):
            return 0
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        def __iter__(self):
            return self
    ?

    @fred1599: Et bien puisque les deux questions qui se sont posées d'elles mêmes sont l'itérable et le fait que l'objet retourné ne correspond pas autant commencer par là, non ?

    @+

  9. #9
    Membre très actif
    Avatar de afranck64
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2009
    Messages
    592
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2009
    Messages : 592
    Par défaut
    @PauseKawa vu que l'objet se doit de retourner du "passe-partout" sous 360°.
    Avec le __iter__:return self, un list(passe_p) produit une liste vide. (on perd en "passabilité-partout" )
    Win 10 64 bits / Linux Mint 18, - AMD A6 Quad: Py27 / Py35
    CONTENU D'UNE QUESTION
    Exemples:
    - Configuration (système d'exploitation, version de Python et des bibliothèques utilisées)
    - Code source du morceau de programme où il y a un bogue
    - Ligne de code sur laquelle le bogue apparaît
    - Erreur complète retournée pas l'interpréteur Python
    - Recherche déjà effectuée (FAQ, Tutoriels, ...)
    - Tests déjà effectués

  10. #10
    Membre Expert
    Inscrit en
    Août 2010
    Messages
    1 124
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 1 124
    Par défaut
    Bonjour,

    Tout d'abord, merci à tous pour vos remarques !

    * Désolé pour l'erreur de vocabulaire. Ce n'est pas un proxy de quelque chose, c'est plutôt un "substituable universel" ("Fourre tout" me fait trop penser à un conteneur)

    * Le cas d'utilisation qui me semble idéal, ce sont deux classes couplées A et B. Dans mon cas, il s'agissait d'un conteneur B (contenant des A) qui s'organise dynamiquement à chaque fois qu'un des attributs d'un de ses éléments est modifié. Le code étant couplé, il était difficile de créer des A() pour faire des tests sans une instance de B. Pour m'en passer, j'ai fait croire à mes instances de A qu'elles étaient contenues dans un passe partout.

    * _ exemple me sert uniquement de hashcode unique. A partir du moment ou l'objet ne contient rien d'intéressant et ne garantit pas la justesse de ce qu'il "renvoie", autant gagner de la mémoire dans les dict ou il apparait.

    * Je vous accorde qu'il est plus naturel de renvoyer self, mais j'ai eu besoin de renvoyer une nouvelle instance pour des boucles (infinies sinon) qui testent l'égalité entre un PassePartout et ce qu'une de ses méthode renvoie. Comme j'imagine aisément des codes qui planteraient dans le cas inverse, il faut rendre ce comportement paramétrable. Idem pour l'itération infinie.

    * Merci pour les tests d'instance, j'avais oublié.

    *
    vu que l'objet se doit de retourner du "passe-partout" sous 360°.
    Avec le __iter__:return self, un list(passe_p) produit une liste vide. (on perd en "passabilité-partout" )
    Bonne idées, mais je ne suis pas certain, à cause de codes qui itérerait jointement (zip par exemple) sur une liste de passepartout, et une liste de fonctions de ceux ci. Je n'en ai pas eu besoin en tout cas. Eventuellement un autre comportement paramétrable

  11. #11
    Membre Expert 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
    Par défaut
    Bonsoir VV33D,

    Bien content de ton retour pour répondre à nos interrogations

    Citation Envoyé par VV33D Voir le message
    * Désolé pour l'erreur de vocabulaire. Ce n'est pas un proxy de quelque chose, c'est plutôt un "substituable universel" ("Fourre tout" me fait trop penser à un conteneur)

    * Le cas d'utilisation qui me semble idéal, ce sont deux classes couplées A et B. Dans mon cas, il s'agissait d'un conteneur B (contenant des A) qui s'organise dynamiquement à chaque fois qu'un des attributs d'un de ses éléments est modifié. Le code étant couplé, il était difficile de créer des A() pour faire des tests sans une instance de B. Pour m'en passer, j'ai fait croire à mes instances de A qu'elles étaient contenues dans un passe partout.
    J'ai besoin d'un exemple là... Merci d'avance

    @+

  12. #12
    Membre Expert
    Inscrit en
    Août 2010
    Messages
    1 124
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 1 124
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    class A(dict):
        """ La classe A a besoin d'une instance de B pour fonctionner  """
        def __init__(conteneur):
            dict.__init__(self)
            self.conteneur=conteneur
        def __setitem__(self,k,v):
            self.conteneur.notify_change(self,k,v)
            dict.__setitem__(self,k,v)
     
    class B:
        pass
    Dans mon cas, B maintient pour chaque (key,value) une liste distincte de ses éléments tels que element[key]== value. Mais on peut imaginer ce qu'on veut : une IHM pour interfacer un objet, un réseau ou on envoie l'information... dans tous les cas, le but est de récupérer des instances de A sans créer un B, qui est en général un objet lourd. Mon approche est de remplacer B par un passepartout

  13. #13
    Membre Expert 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
    Par défaut
    deux classes couplées A et B
    Et le lien entre A et B ?
    Un exemple sur la base du code poster svp

  14. #14
    Membre Expert
    Inscrit en
    Août 2010
    Messages
    1 124
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 1 124
    Par défaut
    dans cet exemple, aucun autre lien que :
    * la classe A a besoin d'un notifiable (appel explicite dans la code)
    * Tous les éléments de ce conteneur notifiable doivent coupler __setitem__ et notify(), de sorte que les listes gérées par notify soient tjs à jour.

    il s’avère que dans mon cas réel, les instances de A accèdent également à B ailleurs pour d'autres raisons.

    Plus généralement, j'ai une classe voiture qui suppose qu'elle possède un moteur et qui lui envoie des ordres (c'est pas ma faute si elle a été mal conçue).
    Je veux tester sans moteur le reste de son comportement (elle croit aussi qu'elle a des pneus, etc), et bien je lui installe un moteur passe partout.

    Bref, réutiliser du code mal conçu (trop couplé?), en ayant le moins d'accident de voiture possible

Discussions similaires

  1. Réponses: 6
    Dernier message: 27/03/2007, 18h43
  2. Réponses: 2
    Dernier message: 18/12/2006, 00h37
  3. [POO] Trouver le type d'un objet passé en argument
    Par FremyCompany dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 28/02/2006, 15h08
  4. [TChart] : objet passé de form en form
    Par PpPool dans le forum Composants VCL
    Réponses: 1
    Dernier message: 29/11/2005, 18h14
  5. [Kylix] Police passe partout
    Par fred78 dans le forum EDI
    Réponses: 2
    Dernier message: 05/08/2003, 23h28

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