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 :

AttributeError: 'LireBase' object has no attribute 'lirePersonnes'


Sujet :

Python

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    265
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2009
    Messages : 265
    Par défaut AttributeError: 'LireBase' object has no attribute 'lirePersonnes'
    Bonjour,

    Je suis complètement nouveau en programmation Python. Ainsi excusez si mon problème est trivial.
    Comme j'ai l'habitude de travailler en JAVA ous Eclipse, j'ai installé l'IDE pour Python.
    J'ai défini 2 classes, dans le package gui. :

    TestListe.py


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    from gui.LireBase import LireBase
     
    class TestListe:
     
        def __init__(self, master):
            self.master = master
            master.title("A simple GUI")
     
    mabase =   LireBase("Personnes")
    liste_personnes = mabase.lirePersonnes()
    et

    LireBase.py


    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
     
     import mysql.connector 
     
    class LireBase:
        table = ""
        def __init__(self,table ):
            self.table= table 
     
     
    #           {Début du code 
     
    def lirePersonnes(self):
            cnx = mysql.connector.connect (
            host="localhost",
            user=xxxe",
            password="",
            database="ma_base"
            )
     
        requete = "SELECT  Naissance, Nom, Prenom, naissance FROM personnes  " 
     
        etc....

    En fait la classe TestListe est beaucoup plus compliquée, car j'utilise TKint pour afficher le résultat de la méthode lirePersonnes(), mais le problème n'est pas là.
    De plus la classe LireBase fonctionne très bien.

    Mon problème est que lorsque j'invoque cette méthode, j'obtiens le message : AttributeError: 'LireBase' object has no attribute 'lirePersonnes'

    Je ne comprends pas très bien comment cela marche, y-a-t-il des attributs particuliers à spécifier de type public, protected, etc... ou comme en C++ il faut définir le prototype de la fonction d'abord ?

    Merci pour votre aide.

    Gérard

  2. #2
    Expert confirmé

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

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 306
    Par défaut
    Salut,

    def lirePersonnes(self): doit être indenté au même niveau que def __init__(self):

    De même que pour toutes autres fonctions que tu créeras dans cette classe. On nomme ces fonctions des méthodes.

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    265
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2009
    Messages : 265
    Par défaut
    Merci pour cette réponse si rapide.
    C'est ce que j'ai fait, et ça marche, à la condition que des fonctions (pas des méthodes) soient placées avant la classe (sans indentation) est-ce normal ?

    Encore merci beaucoup pour ton aide.

    Gégé

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    265
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2009
    Messages : 265
    Par défaut
    J'ai placé mes fonctions au même niveau que "Class" et après le constructeur et cela fonctionne bien : Génial!!!!

  5. #5
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 823
    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 823
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par GérardMartinelli Voir le message
    J'ai placé mes fonctions au même niveau que "Class" et après le constructeur et cela fonctionne bien : Génial!!!!
    Une fonction placée au même niveau que Class n'est alors plus une méthode de la classe, c'est une simple fonction. Oui ça fonctionne aussi mais ce n'est pas la même chose.
    Exemple1
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class cercle:
    	def __init__(self, rayon): self.rayon=rayon
    	def perimetre(self): return 3.1416 * self.rayon * 2
     
    c=cercle(5)
    print(c.perimetre())
    Dans cet exemple, perimetre() est une méthode de cercle. Elle ne peut être appelée que pour un cercle.

    Exemple2
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class cercle:
    	def __init__(self, rayon): self.rayon=rayon
    def perimetre(self): return 3.1416 * self.rayon * 2
     
    c=cercle(5)
    print(perimetre(c))
    Dans cet exemple, perimetre() est une fonction générale. Donc bien qu'elle soit prévue pour traiter un cercle, on peut lui passer n'importe quoi (risque de bug accru). De plus pour fonctionner elle a besoin d'accéder au rayon du cercle qu'elle reçoit (attribut). Ca marche tant que l'attribut est public (accessible de l'extèrieur) sauf que les attributs publics généralement les programmeurs n'aiment pas (n'importe qui peut les modifier de façon anarchique) donc généralement on les met en privé => la fonction ne fonctionnera plus.

    Et enfin le jour où on veut rajouter une autre classe "carré", il faudra créer une seconde fonction avec un nom adapté pour calculer son périmètre. Il faudra aussi modifier le nom de celle-ci et reprendre cette modification partout où elle est utilisée.

    Bref oui mettre ta fonction au même niveau que Class ça "marchotte" mais ça a beaucoup d'inconvénients qu'en faire une vraie méthode. Surtout si elle est spécifique à ta classe.
    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
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 709
    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 709
    Par défaut
    Citation Envoyé par GérardMartinelli Voir le message
    J'ai placé mes fonctions au même niveau que "Class" et après le constructeur et cela fonctionne bien : Génial!!!!
    A la base une méthode est une fonction qui aura l'objet en premier argument qu'on nomme "self" par convention.
    Si on définit cette fonction en dehors de la classe, il faudra passer l'objet en premier argument.
    exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    >>> def f(self):
    ...     print(self.a)
    ...
    >>> class A:
    ...     def __init__(self, a):
    ...         self.a = a
    ...
    >>> a = A('toto')
    >>> f(a)
    toto
    ça marche mais ça ne fait pas de f une méthode pouvant être appelée avec la syntaxe "normale" (objet).(methode):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    >>> a.f()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: 'A' object has no attribute 'f'
    >>>
    Il faut l'ajouter dans la définition de la classe:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    >>> A.f = f
    >>> a.f()
    toto
    >>>
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    265
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2009
    Messages : 265
    Par défaut
    Merci beaucoup pour cet éclairage sur la façon de programmer sous Python. Il me semble toutefois, qu'on devrait faire la différence entre les méthodes (publiques) et celles privées qui en fait ne sont que des fonctions. Sauf si il y a quelque héritage prévue par la suite.

    J'utilise beaucoup les tutoriels pour me former en Python. Venant de Java je n'ai pas trop de mal à m'y retrouver. Toutefois au premier abord, l'importance de l'indentation est très surprenante. Mais ce qui m'interpelle le plus, c'est l'utilisation de self dans la définition des méthodes. Je ne comprends pas bien à quoi cela peut servir si ce n'est jamais utilisé dans la méthode, alors que je comprends parfaitement son importance dans les constructeurs.

    Merci encore pour tout.

    Gégé

  8. #8
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 709
    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 709
    Par défaut
    Citation Envoyé par GérardMartinelli Voir le message
    Merci beaucoup pour cet éclairage sur la façon de programmer sous Python. Il me semble toutefois, qu'on devrait faire la différence entre les méthodes (publiques) et celles privées qui en fait ne sont que des fonctions. Sauf si il y a quelque héritage prévue par la suite.
    Les méthodes privées et protégées existent via des préfixes "__" et "_" (respectivement).

    Citation Envoyé par GérardMartinelli Voir le message
    Mais ce qui m'interpelle le plus, c'est l'utilisation de self dans la définition des méthodes. Je ne comprends pas bien à quoi cela peut servir si ce n'est jamais utilisé dans la méthode
    Utilisé ou pas a.f() sera traduit en A.f(a) (voir mon exemple): une fonction appelée avec l'objet en premier argument. Appeler cet argument "self" est une convention.
    Après, une méthode qui n'accède pas aux attributs de l'objet est une méthode "bizarre" (pourquoi la ranger dans la "class"?)

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

  9. #9
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 823
    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 823
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par GérardMartinelli Voir le message
    Merci beaucoup pour cet éclairage sur la façon de programmer sous Python. Il me semble toutefois, qu'on devrait faire la différence entre les méthodes (publiques) et celles privées qui en fait ne sont que des fonctions. Sauf si il y a quelque héritage prévue par la suite.
    Une méthode privée n'est pas qu'une fonction. C'est une méthode comme les autres. Sauf qu'elle n'est pas accessible de l'extérieur.

    Citation Envoyé par GérardMartinelli Voir le message
    Toutefois au premier abord, l'importance de l'indentation est très surprenante.
    Oui, son créateur en avait marre des programmeurs qui codent sans indenter. Il a donc voulu un langage où c'est l'indentation qui fait le bloc.

    Citation Envoyé par GérardMartinelli Voir le message
    Mais ce qui m'interpelle le plus, c'est l'utilisation de self dans la définition des méthodes. Je ne comprends pas bien à quoi cela peut servir si ce n'est jamais utilisé dans la méthode, alors que je comprends parfaitement son importance dans les constructeurs.
    Où as-tu vu que self n'est jamais utilisé ??? Dans mon premier exemple je l'utilise...
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    class cercle:
    	def __init__(self, rayon): self.rayon=rayon
    	def perimetre(self): return 3.1416 * self.rayon * 2
    En fait, toute méthode d'un objet utilisera obligatoirement les attributs de l'objet sinon elle n'a rien à faire dans l'objet.

    Ensuite il existe des méthodes qui s'appliquent à l'objet en général sans forcément s'appliquer à une instance spécifique d'un objet (méthodes statiques). Dans ce cas effectivement self n'est pas utilisé mais il ne fait pas non plus partie des arguments
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class point:
    	milieu=staticmethod(lambda x, y : (x.__v + y.__v) / 2)		# Méthode statique directement créée par une lambda recevant deux objets points
     
    	# Le constructeur
    	def __init__(self, v): self.__v=v
     
    >>> p1=point(4)
    >>> p2=point(8)
    >>> point.milieu(p1, p2)
    6.0

    Autre syntaxe possible
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class point:
            @staticmethod                                   # On signale que ce qui suit sera une méthode statique
    	def milieu(x, y): return (x.__v + y.__v) / 2	# On définit la méthode en question
     
    	# Le constructeur
    	def __init__(self, v): self.__v=v
     
    >>> p1=point(4)
    >>> p2=point(8)
    >>> point.milieu(p1, p2)
    6.0
    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]

  10. #10
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    265
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2009
    Messages : 265
    Par défaut
    Merci, je crois avoir compris. Lorsqu'on l'on écrit

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
     
    def f(self,toto)
        self.toto = toto
    est-ce bien un moyen dynamique de définir la variable toto pour la classe ?

    Gégé

  11. #11
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 823
    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 823
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par GérardMartinelli Voir le message
    Merci, je crois avoir compris. Lorsqu'on l'on écrit

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    def f(self, toto)
        self.toto = toto
    est-ce bien un moyen dynamique de définir la variable toto pour la classe ?
    Exact (pour peu que l'on appelle ensuite la méthode f() à un moment où à un autre). C'est pour ça que généralement on fait ça dans la méthode __init__() qui est automatiquement appelée quand on instancie cette classe (instancier une classe=créer une variable de cette classe).
    Cette variable "toto" se nomme alors attribut d'instance.
    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]

  12. #12
    Expert confirmé Avatar de papajoker
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2013
    Messages
    2 321
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nièvre (Bourgogne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2013
    Messages : 2 321
    Par défaut
    Citation Envoyé par GérardMartinelli Voir le message
    self dans la définition des méthodes. Je ne comprends pas bien à quoi cela peut servir si ce n'est jamais utilisé dans la méthode, alors que je comprends parfaitement son importance dans les constructeurs.
    Lorsque tu écris
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    mon_objet.lire_personnes(variable)
    il faut comprendre que python va en fait le remplacer en interne par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ClassName.lire_personnes(mon_objet, variable)
    Il me semble toutefois, qu'on devrait faire la différence entre les méthodes (publiques) et celles privées
    Attention class._nom_de_la_méthode_privée() n'est qu'une convention de nommage ! elle indique "privé" au développeur mais elle reste accessible de l'extérieur. Donc grosse différence avec java...

    est-ce bien un moyen dynamique de définir la variable toto pour la classe ?
    Attention : pas pour la classe mais uniquement pour l'instance (l'objet)
    Comme en java, existe aussi des variables de classe en python, mais ces attibuts ne sont pas définis dans le bloc __init__()

    ----

    ps: en plus des tutos tu as la doc officielle (en fr)

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

Discussions similaires

  1. AttributeError "nonetype" object has no attribute
    Par Invité dans le forum Général Python
    Réponses: 2
    Dernier message: 14/12/2010, 20h49
  2. Selenium - AttributeError: 'module' object has no attribute
    Par bender1979 dans le forum Général Python
    Réponses: 4
    Dernier message: 09/11/2010, 22h03
  3. Probleme : AttributeError: 'tuple' object has no attribute
    Par MrGecko dans le forum Général Python
    Réponses: 1
    Dernier message: 27/05/2007, 09h59
  4. Réponses: 2
    Dernier message: 26/05/2006, 14h48

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