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 :

class, instance, attribut, propriété et compagnie


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 23
    Par défaut class, instance, attribut, propriété et compagnie
    bonjour à tous,

    j'essaye désespérément de me créer ma propre ORM
    avec la possibilité de vérifier ou transformer le type de la valeur passée

    pour cela, je me suis tourné d'abord vers les attributs

    en redéfinissant le __setattr__ et le __getattr__
    j'arrive à m'en sortir

    mais du coup, je ne peux plus instancier mon objet :

    class utilisateur(object):
    nom= "default"
    ...........


    user1 =utilisateur()
    user2 =utilisateur()
    user1.nom = "nouveau"
    print user2.nom -> me retourne "nouveau"

    premier arrachage de cheveux, mais j'ai compris que j'avais crée une variable pour ma classe, donc commune à toute mes instances

    j'ai le même problème avec les property et les fget, fset, fdel

    et impossible de le faire avec une instance

    pourtant , quand je regarde la doc d'une ORM comme elixir

    class utilisateur(Entity):
    nom = Field (je sais plus trop la syntax )

    je peux bien instancier utilisateur sans aucun probléme, et quand j'assigne une valeur à nom, il reste toujours en type Field et nom en type String

    j'ai bien essayé de décortiquer le code d'Elixir, mais Entity dérive de Property qui dérive de ... qui dérive de .....................
    deuxieme arrachage de cheveux

    donc je suis preneur si quelqu'un peux me donner une piste pour résoudre mon problème
    ou du moins qui a un peu pitié de mon cuir chevelu

    merci de votre aide, bon weekend

    Kermit

    [edit]:
    j'ai oublié de precier
    j'ai essayé une autre méthode :
    retourné la valeur dans un dictionnaire "d'instance", qui contient les mêmes key que mes attributs, dans le __getattr__
    mais la, le __getattr__ s'appelle en boucle jusqu'à qu'une erreur soit levée

  2. #2
    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
    Bonsoir,

    Je ne suis pas sûr d'avoir compris ce que tu veux faire, mais si tu préfixes le nom de variable par self (c'est à dire "self.nom=..." au lieu de "nom=..."), tu crées une variable propre à chacune des instances de la classe.

    Tyrtamos

  3. #3
    Membre émérite
    Avatar de Antoine_935
    Profil pro
    Développeur web/mobile
    Inscrit en
    Juillet 2006
    Messages
    883
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur web/mobile

    Informations forums :
    Inscription : Juillet 2006
    Messages : 883
    Par défaut
    Salut.

    J'ai un peu de code, en vrac, qui pourrait peut-être t'éclaircir la voie

    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
    In [9]: class Property:
       ...:     def __init__(self, name, type):
       ...:         self.__name = name
       ...:         self.__type = type
       ...:
       ...:     @property
       ...:     def name(self):
       ...:         return self.__name
       ...:
       ...:     @property
       ...:     def type(self):
       ...:         return self.__type
       ...:
       ...:
     
    In [10]: class Model:
       ....:     name = Property("name", "varchar(255)")
       ....:     role = Property("role", "varchar(50)")
       ....:     id   = Property("id", "integer")
       ....:
       ....:
     
    In [11]: dir(Model)
    Out[11]: ['__doc__', '__module__', 'id', 'name', 'role']
     
    In [12]: Model.name
    Out[12]: <__main__.Property instance at 0x02DCEBE8>
     
    In [13]: Model.name.name
    Out[13]: 'name'
     
    In [14]: Model.name.type
    Out[14]: 'varchar(255)'
     
    In [15]: Model.id.type
    Out[15]: 'integer'
     
    In [16]: object = Model()
     
    In [17]: object.name = "Antoine"
     
    In [18]: object.role = "Developer"
     
    In [19]: object.id = 1
     
    In [20]: Model.name
    Out[20]: <__main__.Property instance at 0x02DCEBE8>
     
    In [21]: object.name
    Out[21]: 'Antoine'

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 23
    Par défaut
    bonsoir,

    @tyrtamos
    je suis d'accord avec toi pour le self.nom
    mais du coup, je n'ai pas le moyen de controller ce que je mets dedans

    @Antoine_935
    que dire ....... merci bcp
    ton code est simple et limpide, et réponds exactement à ce que je veux
    j'avais pourtant tourné les attribut, property et leurs accesseurs dans tout les sens, mais pas dans celui la, il faut croire

    encore merci pour la reponse et la réactivité

    Kermit

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 23
    Par défaut
    Bonjour,

    suite a un petit retour de mail avec Antoine, je reviens dessus, car je suis allé un peu vite sur le bouton "Résolu"

    on est d'accord que je veux reprendre le principe d'un orm, je ne peux pas réutilisé un existant car mes données ne viennent pas forcement d'une base sql.

    Mon but :
    - pouvoir "typé" une variable d'instance
    - faire d'autre manip a l'assignation, comme la MAJ de mon affichage

    le code qui se rapproche le plus de ce que je veux :
    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
     
    class field(object):
        def __init__(self):
            self._val = None
     
        def get(*args):
            self = args[0]
            return self._val
     
        def set(*args):
            self = args[0]
            value = args[-1]
            #LA, je suis heureux, car je peux faire mon cast, mon affichage, etc...
            self._val = value  
     
        val = property(fget=get, fset=set, doc='value of field')
     
    class Model(object):
        def __init__(self):
            f=field()
            setattr(self.__class__,  "name",property(fget=f.get,  fset=f.set) )
     
     
     
    mod1= Model()
    mod2= Model()
    mod1.name = "toto"
    print mod2.name
    ..........."toto"
    j'ai bien compris que name devient un attribut de class, donc je modifie mod1.name, je modifie l'attribut de class de Model, donc également de mod2

    je voudrais avoir la même, mais pour une variable d'instance
    La proposition d'Antoine me paraissait alléchante :
    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
     
    class field:
        def __init__(self, name, type):
            self.__name = name
            self.__type = type
     
        @property
        def name(self):
            return self.__name
     
        @property
        def type(self):
            return self.__type
     
     
     
    class Model:
            name = field("name", "varchar(255)")
     
    mod1= Model()
    mod2= Model()
    mod1.name = "toto"
    mod2.name = "titi"
    print mod1.name
    ....'toto'
    print mod2.name
    ....'titi'
    print type(mod1.name)
    ...<type 'str'>
    ici j'ai bien des valeurs d'instance
    mais quand j'assigne une chaine à ma variable name, cela "écrase" mon type field

    je voudrais éviter de passer par des fonction setName, getName, car avec bcp de champ, cela va être lourd à la déclaration.

    dans l'utilisation du code aussi, autant à l écriture que pour sa compréhension

    societe.adresse me retourne une chaine
    societe.adresse.ville me retourne la ville

    plus sexy que
    societe.getAdresse().getString()
    societe.getAdresse().getVille().getString()

    peut être que j'essaye de faire quelque chose d'impossible en python, pourtant, je reviens sur l'exemple d'Elixir de mon premier poste, qui fonctionne bien

    merci pour votre attention, j'espere que sur le cout, j'ai été clair

    Kermit

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

    Ce que tu fais est un peu trop compliqué pour moi, mais je peux au moins te parler des variables de classe.

    Si name est une variable de classe et si tu cherches, de l'extérieur de la classe, à affecter à name une nouvelle valeur en préfixant avec une instance (ex: mod1.name=...), tu crées en fait une nouvelle variable d'instance (comme si tu l'avais déclarée dans la classe avec self.name) qui masque la variable de classe.

    Donc: si name est une variable de classe, il ne faut y accéder (de l'extérieur de la classe comme de l'intérieur des méthodes de la classe) qu'en la préfixant avec le nom de la classe: Model.name, ceci pour l'affectation et pour la lecture de sa valeur.

    Pour la lecture, il apparait qu'on peut accéder à la valeur de la variable de classe en la préfixant par une instance, mais seulement s'il n'existe pas une variable d'instance de même nom. C'est donc assez risqué, et il vaut mieux s'en tenir au nom de la classe.

    Tyrtamos

  7. #7
    Membre émérite
    Avatar de Antoine_935
    Profil pro
    Développeur web/mobile
    Inscrit en
    Juillet 2006
    Messages
    883
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur web/mobile

    Informations forums :
    Inscription : Juillet 2006
    Messages : 883
    Par défaut
    Si j'ai bien compris, tu veux accéder aux "fields" définis dans la classe.
    A priori, tu devrais pouvoir y accéder comme suit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    object.__class__.<nom du champ>

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

Discussions similaires

  1. C++ classe et attributs
    Par kouack dans le forum C++
    Réponses: 7
    Dernier message: 24/04/2008, 14h43
  2. Propriétés d'une classe selon attribut
    Par Papy214 dans le forum Windows Forms
    Réponses: 2
    Dernier message: 10/03/2008, 17h02
  3. Quels classes utiliser pour remplacer des classes qui sont propriété de Sun
    Par danyboy85 dans le forum API standards et tierces
    Réponses: 3
    Dernier message: 21/11/2007, 16h36
  4. Classe fille sans propriété supplémentaire
    Par boutss dans le forum Langage
    Réponses: 6
    Dernier message: 28/03/2007, 09h50
  5. Réponses: 5
    Dernier message: 05/05/2006, 09h40

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