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'attributs privés dans une méthode publique!


Sujet :

Python

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2015
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2015
    Messages : 2
    Points : 1
    Points
    1
    Par défaut Problème d'attributs privés dans une méthode publique!
    Bonjour,

    J'ai commencé le python il y a très peu de temps car je suis entré dans un BTS SN (Système Numérique) et que j'avais envie de m'avancer un peu tout seul.
    On m'a prêté un LINUX Mag Hors-série n°77 "Et maintenant j'apprends la PROGRAMMATION ORIENTEE OBJET ...en 6 jours".

    Je bloque au 2eme/3eme, j'suis pas une flèche.

    Je vous expose le code, puis mon problème:

    Je dois créer un jeu de carte. Donc je créé une première classe, qui va être la Carte.

    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
    class Carte:
    #Les différentes valeurs que peut avoir une carte
        couleurs = ("Coeur", "Pique", "Trèfle", "Carreau")
        valeurs = (None, None, "Deux", "Trois", "Quatre", "Cinq", "Six", "Sept", "Huit", "Neuf", "Dix", "Valet", "Dame", "Roi", "As")
     
     
    #On initialise la classe, une carte sans attributs donnés sera Roi de Trèfle.
        def __init__(self, val=13, coul=3):
     
            while val < 2 or val > 14:
                print("Erreur : La valeur d'une carte doit être comprise entre 2 et 14. Quelle valeur ?")
                val = int(input())
     
            while coul < 0 or coul > 3:
                print("Erreur : La couleur d'une carte doit être comprise entre 0 et 3. Quelle couleur ?")
                coul = int(input())
     
            self.__couleur = coul
            self.__valeur = val
     
        def __getValeur(self):
     
            print("hue")
            return self.__valeur
     
        def __setValeur(self, val):
     
            print("hue1")
            self.__valeur = val
     
    # On passe par une méthode publique pour accéder à des attributs privés
        valeur = property(__getValeur, __setValeur)
     
     
        def __getCouleur(self):
     
            print("hue")
            return self.__couleur
     
        def __setCouleur(self):
     
            print("hue1")
            self.__couleur = couleur
     
        couleur = property(__getCouleur, __setCouleur)
     
        def __str__(self):
     
            return str(Carte.valeurs[self.__valeur] + " de " + Carte.couleurs[self.__couleur])
    Alors déjà ici j'ai un problème avec le principe de méthode publique. Quand j'écris le code de cette façon, tout marche. Mais si j'ai le malheur par exemple de changer de place les deux fonctions dans la property de valeur (ou de couleur), j'ai le droit à cette erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    >>> from Carte import Carte
    >>> c=Carte()
    >>> c.valeur = 5
    Traceback (most recent call last):
        File "<input>", line 1, in <module>
    TypeError: __getValeur() takes 1 positional argument but 2 were given
    >>> print(c.valeur)
    Traceback (most recent call last):
        File "<input>", line 1, in <module>
    TypeError: __setValeur() missing 1 required positional argument : 'val'
    >>>
    Alors, je sais qu'il essaie de rentrer dans la mauvaise fonction et il râle parce qu'il lui manque un truc ou qu'il y en a trop. Mais je ne sais pas comment régler le problème...

    Et ça n'est que le début! Mais déjà, je pense que si on arrive à régler ce problème précisément, ça règlera le suivant étant donné que je retrouve la même erreur pour le même problème (l'attribut privé est __deck et en fait je veux ajouter une carte dans un deck vide. Il me dit aussi qu'il " missing 1 required positional argument : 'carte' ". Seulement le problème est un peu plus complexe parce qu'une autre erreur survient après. Mais on verra plus tard. Si vous décidez de m'aider, bien sûr.

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    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 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Salut,

    Impossible de reproduire le problème mentionné avec le code que vous avez posté:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Python 3.4.0 (v3.4.0:04f714765c13, Mar 16 2014, 19:25:23) [MSC v.1600 64 bit (AM
    D64)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> from Carte import Carte
    >>> c = Carte()
    >>> print (c)
    Roi de Carreau
    >>> c.valeur = 5
    hue1
    >>> print (c)
    Cinq de Carreau
    >>>
    Si vous utilisez Python 2.7, il faut que Carte soit sous classe d'object pour que les property fonctionnent.

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

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2015
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2015
    Messages : 2
    Points : 1
    Points
    1
    Par défaut
    Re,

    Déjà, merci pour votre réponse rapide!

    Je suis en python 3.5.0. Et pardonnez moi j'ai oublié de préciser. J'utilise l'IDE que le linux mag m'a conseillé (sur mac os x 10.9) : Eclipse Mars.

    En fait lorsque le code est écrit de cette manière, il fonctionne mais si j’intervertis les propriétés de valeur, il ne fonctionne plus. Et je ne comprends pas pourquoi, est ce que l'ordre est si important dans les parenthèses ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    valeur = property(__setValeur, __getValeur)
    couleur = property( __setCouleur, __getCouleur)
    à la place de

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    valeur = property(__getValeur, __setValeur)
    couleur = property( __getCouleur, __setCouleur)


    PROBLEME RESOLU : la méthode property permet en fait de choisir entre 4 fonctions qui doivent avoir un ordre précis d'écriture. Je n'avais pas compris ça.

    J'ai d'autres soucis, mais j'vais déjà bien relire ce que j'ai fais avant de venir vous embêter, du coup.

    NOUVEAU PROBLEME : Un problème de FOR.

    Alors, voici la source :

    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
    from Carte import Carte
     
    class Jeu_Cartes:
     
        def __init__(self, vide=False):
     
            self.__deck = []
     
            if not vide:
                for val in range(2, 15):
                    for coul in range(4):
                        self.__deck.append(Carte(val, coul))
     
        def __getdeck(self):
     
            return self.__deck
     
        def __setdeck(self, carte):
     
            if len(self.__deck) > 52:
                raise Exception ("Jeu complet!")
            self.__deck.append(carte)
     
        deck = property(__getdeck, __setdeck)
     
        def tirer(self):
     
            try:
                self.__deck.pop(0)
            except IndexError as erreur:
                print("Il n'y a plus de carte dans le deck!")
                return None
     
        def __str__(self):
     
            cartes_du_jeu=""
            for Carte in self.__deck:
                if cartes_du_jeu == "":
                    cartes_du_jeu = str(Carte)
                else:
                    cartes_du_jeu += "\n" + str(Carte)
     
            return cartes_du_jeu
    Avec ceci, et la source précédente (pour Carte), on doit avoir moyen de créer donc un deck de 52 cartes, toutes les cartes possibles en fonction des différentes couleurs et valeurs.
    J'avais décidé de retirer toute les cartes du deck de 52 cartes pour voir si ça marchait, si j'avais bien compris le principe du "for". Deux façons de l'écrire, mais déjà on appelle le tout :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    >>> from Jeu_Carte import Jeu_Cartes
    >>> j=Jeu_Cartes
    >>> for i in j.deck:
    .  .  .    j.tirer()
    .  .  .
    >>> print(j)
    Comme je dois tout réécrire à la main, j'vais plutôt expliquer le résultat : il va me donner toutes les cartes de Huit de Coeur à As de Trèfle ( pour le print(j) ). Autrement dit, la boucle aura retiré les 26 premières cartes de la liste.
    Faire un print(i) dans la boucle va me rendre la première carte du deck, puis en sauter une, puis me rendre la suivante, puis en sauter une, etc...

    Je peux comprendre que la boucle "saute" une carte à chaque fois parce que j'appelle une liste qui se modifie au fur et à mesure que le for avance. Mais je ne comprends pas le rapport entre les deux, et donc le problème.

    Par contre quand j'écris la boucle de cette manière, tout marche niquel, enfin ça ne me donne pas la réponse à mon problème :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    >>> from Jeu_Carte import Jeu_Cartes
    >>> j=Jeu_Cartes
    >>> for i in range(len(j.deck)):
    .  .  .    j.tirer()
    .  .  .
    >>> print(j)
     
    >>>

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    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 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Salut,

    Citation Envoyé par Hjaldori Voir le message
    PROBLEME RESOLU : la méthode property permet en fait de choisir entre 4 fonctions qui doivent avoir un ordre précis d'écriture. Je n'avais pas compris ça.
    La méthode "property" est d'abord une fonction.
    Si on écrit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    >>> def f(a, b):
    ...     return a * 2 + b
    ...
    >>> f(3, 1)
    7
    >>> f(1, 3)
    5
    facile de voir que l'ordre des paramètres est important.

    Mais Python a plus d'un tour dans son sac:
    Citation Envoyé par Hjaldori Voir le message
    Je peux comprendre que la boucle "saute" une carte à chaque fois parce que j'appelle une liste qui se modifie au fur et à mesure que le for avance. Mais je ne comprends pas le rapport entre les deux, et donc le problème.
    Si vous parcourez les éléments d'une liste via une boucle et que vous modifiez la liste dans la boucle, le résultat est imprédictible: quand on programme, on n'aime pas du tout les résultats imprédictibles...
    Essayez de réduire votre code à un exemple plus simple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    >>> L = list(range(6))
    >>> for e in L:
    ...     L.pop(0)
    ...     print(e)
    ...
    0
    0
    1
    2
    2
    4
    Si on fait "print" avant "pop":

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    >>> L = list(range(6))
    >>> for e in L:
    ...     print(e)
    ...     L.pop(0)
    ...
    0
    0
    2
    1
    4
    2
    >>>
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  5. #5
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 048
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 048
    Points : 1 378
    Points
    1 378
    Par défaut
    c'est mal de modifier une liste pendant son parcourt ...

Discussions similaires

  1. Probléme de retour d'un type ArrayList dans une méthode JAVA
    Par KnowPart dans le forum Collection et Stream
    Réponses: 20
    Dernier message: 21/01/2011, 09h40
  2. Réponses: 2
    Dernier message: 14/11/2008, 11h25
  3. Problème de const et de pointeur dans une méthode
    Par Vonziz dans le forum Débuter
    Réponses: 15
    Dernier message: 18/09/2008, 14h41
  4. Réponses: 7
    Dernier message: 26/02/2008, 20h49
  5. Réponses: 3
    Dernier message: 14/04/2007, 16h06

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