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__ pour initialiser un attribut de classe


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre à l'essai
    Homme Profil pro
    Enseignant
    Inscrit en
    Juillet 2013
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4
    Par défaut __setattr__ pour initialiser un attribut de classe
    Bonjour à tous,

    je me permets encore de faire appel à vos lumières.
    Je voudrais pouvoir initialiser de nombreuses variables globales (avec quelques traitements) comme attribut de classe et je pensais à un code du genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    glob=[1,2,3]
    class Ini(object):
    	'''initialisation des constantes globales dans une classe'''
    	listfixe=['glob']
    	def __init__(self):
    		Ini.__setattr__(self,'glo',glob)
    		#object.__setattr__(Ini,'glo',glob)
    		Ini.glo=self.glo
     
    ini=Ini()
    print(ini.glo)
    #object.__setattr__(Ini,'glo',glob)
    print(Ini.glo)
    Ce que je voudrais c'est pouvoir faire l'équivalent de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Ini.__setattr__(self,'glo',glob)
    qui crée un attribut d'instance, mais pour créer un attribut de classe. Cela fonctionne avec mais je n'arrive pas à en trouver l'équivalent avec pour créer un attribut de classe.
    Merci d'avance de vos lumières.

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

    Ca serait bien d'apprendre à utiliser le help:
    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
    >>> help(A.__setattr__)
    Help on wrapper_descriptor:
     
    __setattr__(self, name, value, /)
        Implement setattr(self, name, value).
     
    >>> help (setattr)
    Help on built-in function setattr in module builtins:
     
    setattr(...)
        setattr(object, name, value)
     
        Set a named attribute on an object; setattr(x, 'y', v) is equivalent to
        ``x.y = v''.
     
    >>>
    et de vous demander quelle peut être, à ce niveau, la différence entre des objets comme "class", "instance", "fonction", "module"....

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

  3. #3
    Membre à l'essai
    Homme Profil pro
    Enseignant
    Inscrit en
    Juillet 2013
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4
    Par défaut
    Merci beaucoup de ta réponse wiztricks même si elle m'a peu aidé (avec ma confrontation avec les classes de python qui date de moins d'une semaine).
    J'ai cependant une solution à l'aide de metaclass :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    glob=[1,2,3]
    class MC(type):
    	def __init__(cls, name, bases, dict):
    		a='glo'
    		setattr(cls, a, glob)
    		super(MC, cls).__init__(name, bases, dict)
     
    class Ini(metaclass=MC):
    	truc=2
     
    print(Ini.glo)
    Je vais donc pouvoir balayer mes variables globales :-)

  4. #4
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 062
    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 062
    Par défaut
    Je ne comprend pas ce que vous souhaitez, __setattr__ (et non __setaddr__ comme dans le titre du topic) permet d'affecter une valeur à un attribut de l'objet créé. Vous dîtes vouloir créer de nombreuses variables globales (en fait qui sont locales à la classe) mais je ne comprend pas bien à quoi se rapporte cela concrètement en termes d'objets dans votre problématique.

    Si vous pouviez exprimer l'intérêt d'utiliser cette méthode, alors il se peut qu'on puisse plus facilement vous diriger.

    Parce-que le dernier code que vous proposez est bien trop complexe par rapport au résultat attendu... Le code ci-dessous fait cela rapidement !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    GLOB = [1, 2, 3]
     
    class Ini:
        glo = GLOB[:]
     
    print(Ini.glo)
    La métaclasse est une techno complexe dans les langages orientés objets, et en règle général, si on se pose la question de son intérêt, c'est quelles ne sont pas utiles. Dans 99% des cas, ce n'est pas utile de les utiliser.

    Qui puis est, attaquer les métaclasses alors que les notions primordiales de la POO ne sont pas maîtrisées, c'est de la folie.

    Avec __setattr__ vous pouvez faire du polymorphisme en contrôlant par exemple le type de l'objet à affecter à la variable de classe.

    Exemple:

    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
    GLOB = [1, 2, 3]
     
    class Ini:
        def __setattr__(self, name, value):
            if isinstance(value, list):
                self.__dict__[name] = value
        def __getattr__(self, name):
            if name in self.__dict__:
                return self.__dict__[name]
     
    ini = Ini()
    setattr(ini, 'glo', 5)
     
    print(ini.glo) # None
     
    setattr(ini, 'glo', GLOB[:])
     
    print(ini.glo) # [1, 2, 3]
    C'est un des intérêt de cette méthode spéciale, c'est de contrôler l'affectation des attributs de votre classe.

    L'attribut de classe, ce que vous souhaitez faire en l'occurrence, permet d'être modifié dès lors où vous créez des instances, c'est en effet une variable commune à toutes les instances. Par exemple, on peut très bien utiliser un compteur permettant de comptabiliser le nombre d'objets créés.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class Ini:
        COMPTEUR = 0
     
        def __init__(self):
            Ini.COMPTEUR += 1
     
    for i in range(2):
        ini = Ini()
        print("l'ID de l'objet est: ", id(ini))
     
    print("Le nombre d'objets créés: ", ini.COMPTEUR)
    Ce qui donne:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    l'ID de l'objet est:  140424966516688
    l'ID de l'objet est:  140424966549632
    Le nombre d'objets créés:  2
    Conclusion:
    Après toutes ces explications, un peu techniques, il est important de savoir qu'avant d'utiliser la POO avec le langage, il faut en trouver un intérêt majeur. Si il y a un intérêt vous devez concevoir graphiquement (UML par exemple) ou pas toutes les entités se rapprochant au plus près de votre problème à résoudre.

  5. #5
    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
    Citation Envoyé par marco_linux Voir le message
    Merci beaucoup de ta réponse wiztricks même si elle m'a peu aidé (avec ma confrontation avec les classes de python qui date de moins d'une semaine).
    Si vous n'avez pas encore compris qu'avec Python tout est objet et qu'on peut écrire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    >>> class A: pass
    ...
    >>> setattr(A, 'foo', 'bar')
    >>> A.foo
    'bar'
    >>>
    Sûr que des choses simples (utiliser une fonction) deviennent fort compliquées alors qu'écrire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    glob=[1,2,3]
    class A:
         glo = glob
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    glob=[1,2,3]
    class A:
         ...
    A.glo = glob
    suffiraient largement.


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

Discussions similaires

  1. Réponses: 2
    Dernier message: 29/08/2012, 11h05
  2. Probleme pour initialiser une classe
    Par geodev dans le forum NetBeans
    Réponses: 1
    Dernier message: 09/12/2010, 22h13
  3. Réponses: 2
    Dernier message: 26/11/2009, 14h00
  4. utilisation de JGraph pour afficher les attributs de classe
    Par Mamy-Laye dans le forum Interfaces Graphiques en Java
    Réponses: 1
    Dernier message: 10/11/2009, 10h58
  5. Réponses: 4
    Dernier message: 28/07/2009, 21h01

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