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 :

__setattr__ et mécanismes de sous reférencement


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 3
    Par défaut __setattr__ et mécanismes de sous reférencement
    Bonjour à tous,

    Je m'excuse par avance si le problème que je vais exposer a déjà été traité sur le forum. J'avoue ne rien avoir trouvé de mon côté bien que vous allez voir que c'est assez basique.

    Voici donc ce que je cherche à faire. J'ai une classe MaClasse qui possède, entre autre (pour l'exemple on va dire qu'il n'y a que lui), un attribut contenant une liste d'entiers (la liste peut être vide). Voici donc le code associé :
    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 MaClasse:
        def __init__( self, LL ):
            self.L = LL
            # Verification que la liste self.L contienne uniquement des entiers 
            self.check()
     
        # On verifie que self.L est une liste et qu'elle est composee d'entiers
        def check( self ):
            if not isinstance( self.L, list ):
                raise AttributeError
            for n in self.L:
                if not isinstance( n, int ):
                    raise AttributeError
     
        def __str__( self ):
            return "self.L = %s" % ( self.L, )
     
        def __repr__( self):
            return str( self )
    Donc voila, je suis content si je tape :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    >>> MaClasse( [] )
    self.L = []
     
    >>> MaClasse( [ 1, 2, -3 ] )
    self.L = [1, 2, -3]
     
    >>> MaClasse( "a" )
    AttributeError: l'attribut doit etre de type list
     
    >>> MaClasse( [ 1, 2, 3.14 ] )
    AttributeError: les elements doivent etre entiers
    Ca a donc l'air de rouler... sauf que si je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    >>> a = MaClasse( [] )
    >>> a.L = [ "a", 2 ]
    self.L = ['a', 2]
    Et là, c'est gênant. Du coup, je panique pas et je définis la méthode spéciale __setattr__ pour gérer le comportement de self.L = xxx. Voila ce que je propose :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
        def __setattr__( self, name, value ):
            if name == "L":
                self.__dict__[ "L" ] = value
                self.check()
            else:
                raise AttributeError, "L'attribut %s n'existe pas" % (name, )
    Maintenant, ça marche je peux faire tranquillement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    >>> a = MaClasse( [] )
    >>> a.L = [ "a", 2 ]
    AttributeError: les elements doivent etre entiers
    Par contre, et c'est là que je sèche, si je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    >>> a = MaClasse( [] )
    >>> a.L = [ 1, 2 ]
    >>> a.L[ 1 ] = "a"
    self.L = [1, 'a']
    Je ne lève malheureusement pas d'exception.

    Je me tourne donc vers vous pour savoir si vous connaissez la méthode "officielle" pour traiter cette problématique de maintien d'intégrité d'objet lors d'affectation.

    Merci d'avance, en espérant avoir été assez clair sur mon problème.

    Waste.

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

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

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

    yep, on peut passer par les property:

    http://docs.python.org/library/functions.html#property

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 3
    Par défaut
    Merci Kango pour ta réponse.

    J'avais déjà entendu un peu parler des "property"... Là, j'ai essayé de suivre la démarche de la doc, ce qui m'a donné ça :
    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
     
    class MaClasseBis( object ):
        def __init__( self, LL ):
            self._L = LL
            # Verification que la liste self.L contienne uniquement des entiers 
            self.check()
     
        # On verifie que self.L est une liste et qu'elle est composee d'entiers
        def check( self ):
            if not isinstance( self._L, list ):
                raise AttributeError, "l'attribut doit etre de type list"
            for n in self._L:
                if not isinstance( n, int ):
                    raise AttributeError, "les elements doivent etre entiers"
     
        def __str__( self ):
            return "self.L = %s" % ( self._L, )
     
        def __repr__( self ):
            return str( self )
     
        #     
        @property
        def L( self ):
            """I'm the 'L' property."""
            return self._L
     
        @L.setter 
        def L( self, value ):
            self._L = value
            self.check()
    Et malheureusement, ça ne marche pas. Si je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    >>> a = MaClasseBis( [ 1, 2, 3 ] )
    >>> a.L[ 0 ] = 'a'
    >>> a
    self.L = ['a', 2, 3]
    Ce qui ne me va pas du tout...

    En tout cas, merci quand même pour ta proposition.

  4. #4
    Membre émérite
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    758
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

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

    Informations forums :
    Inscription : Décembre 2007
    Messages : 758
    Par défaut
    ok,

    dans ce cas, tu as besoin de sous classer le type liste de base et de surdéfinir __setitem__ afin d'imposer le contrôle que tu souhaites:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class MyList(list):
        def __init__(self,*args,**kwargs):
            list.__init__(self,*args,**kwargs)
        def __setitem__(self,key,value):
            list.__setitem__(self,key,int(value))
    ça peut ne pas suffire bien entendu, tu peux avoir les méthodes append, insert, extend à sous-classer également

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

    Au cas ou vous avez dans python-forum une discussion sur le sujet avec une implémentation de liste restreintes à un type qui me paraît assez complète.

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

  6. #6
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 3
    Par défaut
    Ok merci pour vos réponses.

    Manifestement, on est obligé de dériver la classe liste de base pour mettre en place les contrôles souhaités. Finalement, en y réfléchissant, ça permet d'être assez rigoureux même si ça peut être chiant dans le cas où ton objet contiendrait plusieurs listes de types différents.

    Bon en tout cas, je sais ce qu'il me reste à faire!

    Merci encore.

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

Discussions similaires

  1. Problème d'installation oracle 8.1.7 sous NT
    Par Anonymous dans le forum Installation
    Réponses: 7
    Dernier message: 02/08/2002, 14h18
  2. webcam : lire sur un port usb en c/c++ ou java. sous win. ?
    Par flo007 dans le forum Choisir un environnement de développement
    Réponses: 2
    Dernier message: 24/05/2002, 23h24
  3. OmniORB : code sous Windows et Linux
    Par debug dans le forum CORBA
    Réponses: 2
    Dernier message: 30/04/2002, 17h45
  4. Je ne peux établir une connexion cliente sous Linux.
    Par Anonymous dans le forum CORBA
    Réponses: 5
    Dernier message: 16/04/2002, 15h57
  5. Réponses: 4
    Dernier message: 27/03/2002, 11h03

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