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 :

Problème d'attribut d'instance de classe


Sujet :

Python

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    105
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 105
    Par défaut Problème d'attribut d'instance de classe
    Bonjour à tous,

    J'ai jusqu'alors toujours reculé devant l'utilisation des classes, mais aujourd'hui, selon l'adage de je ne sais plus qui (R. Devos ?) "ce n'est pas en remettant la catastrophe à plus tard qu'on l'évite", je me lance...
    J'ai créé un programme permettant de convertir un nombre d'une base dans une autre : il marche très bien ...
    Cependant, j'étais obligé soit de définir la variable chfr (cf mon code) dans chaque fonction + dans la fonction qui contrôlait la validité du nombre par rapport à la base choisie, soit de la passer en argument dans l'appel de la fonction...
    Ceci ne m'a pas paru rationnel et je me suis dit que c'était l'occasion ou jamais, d'attaquer les classes et d'encapsuler ces deux fonctions (voire peut-être plus tard le choix du nombre également) dans une classe...
    Et là, après une matinée d'efforts, je coince...
    Voilà le code élagué de 3 fonctions : le choix de la base de départ (avec contrôles), le choix du nombre (avec contrôles) et le choix de la base d'arrivée (avec contrôles). :
    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
     
    # usr/bin/env python
    # -*- coding: cp1252 -*-
     
    from __future__ import division
    from math import log
     
    class conversion:    
        def __init_(self):
            self.chfr='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
     
        def versdix(self,s,b):
            s,l,nb=s[::-1],len(s),0
            for i in xrange(l):       
                nb+=self.chfr.find(s[i])*b**i
            return nb
     
        def versbase(self,s,b):
            nb,nbdiv='',int(log(s)//log(b))+1
            for i in xrange(nbdiv):
                s,r=nbcr//b,s%b
                nb=self.chfr[r]+nb
            return nb                    
     
    bd,s,ba=16,'ABCD',2
     
    # Affichage des données
    print'\n Le nombre'
    print '    '+s
    print ' écrit en base',bd
     
     
    # Calculs
    c=conversion()
    if bd!=10:
        nbcr=c.versdix(s,bd)
    else:
        nbcr=int(s)
    if ba !=10:
        rep=c.versbase(nbcr,ba)
    else:
        rep=str(nbcr)   
     
    #Affichage de la réponse
    print '\n s\'écrit'
    print '    '+rep
    print ' en base '+str(ba)
    Message d'erreur, là je sèche :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Traceback (most recent call last):
      File "C:/Python26/ConvertBaseClass3.py", line 35, in <module>
        nbcr=c.versdix(s,bd)
      File "C:/Python26/ConvertBaseClass3.py", line 14, in versdix
        nb+=self.chfr.find(s[i])*b**i
    AttributeError: conversion instance has no attribute 'chfr'
    Il me serait très agréable que l'un de vous puisse me souffler la solution qui doit certainement être évidente...
    J'ai pourtant modifié un des programmes de Swinnen ainsi (juste pour tester le self.chfr.find('Z')) et là, pas d'erreur...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class Voiture:
        def __init__(self):
            self.couleur = 'rouge'
            self.marque = 'Ford'
            self.chfr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
     
     
        def affiche(self):
            print "%s %s, vitesse = %s m/s" % \
            (self.marque, self.couleur, self.chfr.find('Z'))     
     
    a = Voiture()
    a.affiche()
    Merci d'avance.

    @+

  2. #2
    Expert confirmé

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 307
    Par défaut
    Puis-je te proposer ceci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    class conversion(object):    
        def __init__(self):
            self.chfr = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    Le "(object)" est dans la définition des classe "new style" mais n'est pas la cause de ton problème, celle-la se trouve une ligne après, mais je te laisse chercher, c'est toujours plus gai quand on trouve soi-même

  3. #3
    Rédacteur
    Avatar de Zavonen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 772
    Détails du profil
    Informations personnelles :
    Âge : 77
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 772
    Par défaut
    coquille
    remplacer __init_ par __init__
    Ce qu'on trouve est plus important que ce qu'on cherche.
    Maths de base pour les nuls (et les autres...)

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    105
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 105
    Par défaut
    Salut les gars,

    Et merci !
    Je suis à baffer... Et je n'ai pas vu un truc pareil ? J'étais centré sur l'écriture de la classe et je pensais avoir fait une erreur là-dedans.
    Bon, bin je préfère ça.
    @zavonen : coquille ça a fait tilt, j'ai regardé s'il y en avait d'autres et j'en ai trouvé. A force de modifier à droite à gauche, c'était fatal.

    @VinsS
    Le "(object)" est dans la définition des classe "new style"
    Ce qui veut dire ? N'oublie pas, c'est la première fois que j'écris une classe !
    Cela voudrait-il dire : même si ça marche sans écrire 'object', c'est comme ça que l'on fait maintenant... ou bien 'si tu ne le fais pas, tu vas rencontrer des problèmes ultérieurement...'

    Merci à vous : ça marche !

    @+

  5. #5
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 830
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 830
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par yoshik Voir le message
    Ce qui veut dire ? N'oublie pas, c'est la première fois que j'écris une classe !
    Cela voudrait-il dire : même si ça marche sans écrire 'object', c'est comme ça que l'on fait maintenant... ou bien 'si tu ne le fais pas, tu vas rencontrer des problèmes ultérieurement...'
    Il s'agit d'une syntaxe conventionnelle. Les parenthèses sont habituellement destinées à contenir la référence à une autre classe ce qui permet le mécanisme d'héritage. Ainsi une nouvelle classe peut hériter d'une classe parente un ensemble de caractéristiques auxquelles elle ajoutera les siennes. Si on crée une classe de base sans héritage, la convention prévoit qu'on indique le nom spécial "object" qui désigne l'ancêtre de tous les objets.
    Il s'agit aujourd'hui d'une simple convention donc ce n'est pas une obligation. Mais demain...?

    Petite remarque sur ton code initial: si tu veux que les éléments qui sont hors de ta classe ne puissent pas accéder à certaines variables de ta classe utilisés pour les algos internes (ce qui semble être le cas de chfr), alors vaut mieux faire précéder la variable de deux underscores. Ca a pour effet de la rendre inaccessible depuis l'extérieur de ta classe (ca évite à un programmeur la tentation d'aller taper dans ladite variable au risque de la modifier par erreur)
    Code Python : 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
    # usr/bin/env python
    # -*- coding: cp1252 -*-
     
    from __future__ import division
    from math import log
     
    class conversion:    
        def __init__(self):
            self.__chfr='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
     
        def versdix(self,s,b):
            s,l,nb=s[::-1],len(s),0
            for i in xrange(l):       
                nb+=self.__chfr.find(s[i])*b**i
            return nb
     
        def versbase(self,s,b):
            nb,nbdiv='',int(log(s)//log(b))+1
            for i in xrange(nbdiv):
                s,r=nbcr//b,s%b
                nb=self.__chfr[r]+nb
            return nb                    
     
    bd,s,ba=16,'ABCD',2
     
    # Affichage des données
    print'\n Le nombre'
    print '    '+s
    print ' écrit en base',bd
     
     
    # Calculs
    c=conversion()
    print c.__chfr     // CETTE INSTRUCTION NE MARCHERA PAS - chfr est invisible depuis le dehors...
    if bd!=10:
        nbcr=c.versdix(s,bd)
    else:
        nbcr=int(s)
    if ba !=10:
        rep=c.versbase(nbcr,ba)
    else:
        rep=str(nbcr)   
     
    #Affichage de la réponse
    print '\n s\'écrit'
    print '    '+rep
    print ' en base '+str(ba)
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  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
    Citation Envoyé par Sve@r Voir le message
    Si on crée une classe de base sans héritage, la convention prévoit qu'on indique le nom spécial "object" qui désigne l'ancêtre de tous les objets.
    Il s'agit aujourd'hui d'une simple convention donc ce n'est pas une obligation. Mais demain...?
    Ce n'est pas juste une convention. Il y a une différence entre une classe déclarée comme héritant de 'object' et une classe n'héritant de rien du tout. C'est lié à l'introduction des classes "new-styles" en Python 2.2.
    Les changements fait à tout le sous-sytème orienté objet de Python dans cette version étaient trop importants pour simplement remplacer l'ancien système. Donc ils ont conservés les deux jusque Python 3.

    Une classe héritant de object (directement ou indirectement en héritant d'une classe qui hérite de object) est une classe "new-style". Les classes n'héritant pas de object (directement ou indirectement) sont dites des classes "classiques".

    Il y a des différences de comportement entre les classes "classiques" et les classes "new-style", bien que la différence ne soit pas apparente pour un usage simple. Par exemple, seules les classes "new-style" permettent d'utiliser les metaclasses, les __slots__ ou __getattribute__. Le système de résolution de méthodes en cas d'héritage multiple n'est pas non plus le même.
    En Python 3, les classes "classiques" ont disparu et il ne reste que les classes "new-style". Par conséquent, en Python 3, il n'est plus nécessaire d'écrire explicitement qu'on hérite de 'object'; toute classe hérite de object par défaut.

  7. #7
    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
    Dividee tu peux me donner in exemple en version 2 et en version 3? Si c'est ce que je pense je passe direct en version 3.

  8. #8
    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
    Un exemple de new-style class ?

    Ben simplement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class Voiture(object):    # new-style class en python 2.x
        ...
     
    class Voiture:            # new-style class en Python 3
        ...
    Enfin en Python 3, on ne parle plus tellement de "new-style classes" car c'est le seul type de classes disponibles, et elles sont plus vraiment "new"

  9. #9
    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
    Ah oui, mais moi je voulais un exemple avec un héritage en version 2.x et voir ce que ça donne en version 3.

    Je n'ai pas de bases en informatique, donc c'est avec des exemples que je comprend.

  10. #10
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    105
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 105
    Par défaut
    Bonsoir,

    Merci pour ce débat intéressant...
    Je partage le souci de fred.
    Dividee, peux-tu montrer un exemple concret, s'il te plaît ?

    @+

  11. #11
    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 bien votre demande. Un exemple concret de quoi ? Il n'y a pas de différence syntaxique entre les deux types de classes, à part que pour faire une classe new-style, on doit toujours hériter de object ou d'une autre classe new-style. En voyant un déclaration comme ceci:
    on ne peut pas savoir (en Python 2.x) si c'est une classe new-style ou classique, cela dépendra du fait que la classe A est elle-même l'une ou l'autre.

    Alors vous voulez une exemple de quoi ? De quelque chose qu'on peut faire avec des classes new-style mais pas des classes classiques ? Il y en a un certain nombre, mais ce sont toutes des choses différentes et une bonne partie ne concerne qu'un usage vraiment avancé.

    Et j'avoue que je ne connais pas toutes les différences, ayant commencé Python avec la version 2.3, je n'ai jamais utilisé que des classes new-style. Apparemment, avec les classes classiques, en plus de ce que j'ai cité plus haut, il n'y a pas non plus de méthode __new__, de properties ou de méthodes statiques.

    Je peux toutefois donner ce conseil: utilisez toujours des classes new-style (en héritant de object s'il n'y a pas d'autre parent). Il n'y a pas de raison d'utiliser encore les classes "classiques".

    fred1599, je ne sais pas à quelles différences tu penses, mais moi je ne vois pas en quoi la suppression des classes classiques justifierait à lui seul le passage en Python 3. La seule différence, c'est l'exemple que j'ai donné dans mon post précédent: en Python 3, on ne doit plus hériter explicitement de object pour créer une classe new-style quand il n'y a pas d'autre parent.

  12. #12
    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
    fred1599, je ne sais pas à quelles différences tu penses, mais moi je ne vois pas en quoi la suppression des classes classiques justifierait à lui seul le passage en Python 3.
    En effet après avoir vu tes explications (j'avais mal compris ta réponse précédente), il n'y a pratiquement rien de changé. Je suis en python 2.6 et j'hérite toujours mes classes de object.

    Donc je te remercie de tes réponses.

  13. #13
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 830
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 830
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par dividee Voir le message
    Ce n'est pas juste une convention. Il y a une différence entre une classe déclarée comme héritant de 'object' et une classe n'héritant de rien du tout. C'est lié à l'introduction des classes "new-styles" en Python 2.2.
    Les changements fait à tout le sous-sytème orienté objet de Python dans cette version étaient trop importants pour simplement remplacer l'ancien système. Donc ils ont conservés les deux jusque Python 3.

    Une classe héritant de object (directement ou indirectement en héritant d'une classe qui hérite de object) est une classe "new-style". Les classes n'héritant pas de object (directement ou indirectement) sont dites des classes "classiques".

    Il y a des différences de comportement entre les classes "classiques" et les classes "new-style", bien que la différence ne soit pas apparente pour un usage simple. Par exemple, seules les classes "new-style" permettent d'utiliser les metaclasses, les __slots__ ou __getattribute__. Le système de résolution de méthodes en cas d'héritage multiple n'est pas non plus le même.
    Ok, merci de cette précision...

    Citation Envoyé par dividee Voir le message
    Et j'avoue que je ne connais pas toutes les différences, ayant commencé Python avec la version 2.3, je n'ai jamais utilisé que des classes new-style. Apparemment, avec les classes classiques, en plus de ce que j'ai cité plus haut, il n'y a pas non plus de méthode __new__, de properties ou de méthodes statiques.
    Ah si !!! Je ne connaissais pas les classes "new-style" avant ce soir et donc tous mes objets sont classiques. Pourtant, on peut y mettre du "__new__" et/ou des propriétés et/ou des méthode statiques (j'en ai assez mis dans tous mes codes pour le savoir !!!)

    Citation Envoyé par dividee Voir le message
    Je peux toutefois donner ce conseil: utilisez toujours des classes new-style (en héritant de object s'il n'y a pas d'autre parent). Il n'y a pas de raison d'utiliser encore les classes "classiques".
    Ben sauf si on n'était pas au courant quoi...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 14/11/2008, 11h25
  2. Attribut statique = instance d'une classe
    Par allserv dans le forum C++
    Réponses: 13
    Dernier message: 03/01/2008, 18h42
  3. Réponses: 6
    Dernier message: 17/12/2007, 16h16
  4. STL Problème avec une liste d'instances de class
    Par BruceBoc dans le forum SL & STL
    Réponses: 12
    Dernier message: 16/02/2007, 14h12
  5. [css]problème d'attribution de classe dans deux listes
    Par Mitaka dans le forum Mise en page CSS
    Réponses: 9
    Dernier message: 24/11/2005, 18h05

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