Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 29/04/2021, à 19:36

chris7522

[RESOLU]Heritage (python)

Bonjour a toutes et a tous ,
   J'ai fait une erreur lors de l'ecriture de mes classes puisque j'ai un message d'erreur . J'ai beau chercher , je ne vois pas ou ca coince .  Je ne maitrise pas encore tout ca , pourtant ca ne doit pas etre grand chose comme dab !

class Vehicule:
    def __init__(self,name,carbu,bVitesse):
        self.nom = name
        self.carburant = carbu
        self.boiteVitesse = bVitesse

    def _getNom(self):
        return self._nom

    def _getCarburant(self):
        return self._carburant
    def _getBvitesse(self):
        return self._boiteVitesse
    nom = property(_getNom)
    carburant = property(_getCarburant)
    boiteVitesse = property(_getBvitesse)
   
    def seDeplacer(self):
        print(f"Le vehicule {self._nom} roule au {self._carburant} et a une boite de vitesse {self._bVitesse}")

   
class Camion(Vehicule):
    def __init__(self,name,carbu,bVitesse,poids,longueur):
        Vehicule.__init__(self,name,carbu,bVitesse)
        self.poids = poids
        self.longueur = longueur

    def _getPoids(self):
        return self._poids
    def _setPoids(self,weight):
        if weight.isalpha == True:
            raise BaseException("Entrez un entier :")
        self._poids = weight
    poids = property(_getPoids,_setPoids)
   
    def _getLongueur(self):
        return self._longueur
    def _setLongueur(self,L):
        if L.isalpha()==True:
            raise BaseException('Entrez un entier :')
        self._longueur = L
    longueur = property(_getLongueur,_setLongueur)
   
    def seDeplacer(self):
        print("Le camion {self._nom} roule au {self._carburant} ,a une boite de vitesse {self._boiteVitesse}, a un poids de {self._poids} et une longueur de {self._longueur}")

c1 = Camion("Turbo22","diesel","automatique",22,2)
c1.seDeplacer()  

Merci de votre regard

Dernière modification par chris7522 (Le 10/05/2021, à 10:42)

Hors ligne

#2 Le 29/04/2021, à 19:46

beuguissime

Re : [RESOLU]Heritage (python)

bonsoir,

Pourrais-tu inclure l'erreur lors de ce genre de demande stp ?

Pourquoi pas comme ceci ?
Pourquoi passer par property() etc ? Ce sont ces lignes qui coincent. Il manque aussi un f devant la chaîne du deuxième print. L'héritage était mal fait. Il faut utiliser super() pour appeler l'initialisation de la classe parente (avec les arguments appropriés).

class Vehicule:
    def __init__(self,name,carbu,bVitesse):
        self.nom = name
        self.carburant = carbu
        self.boiteVitesse = bVitesse

    def seDeplacer(self):
        print(f"Le vehicule {self.nom} roule au {self.carburant} et a une boite de vitesse {self.bVitesse}")

class Camion(Vehicule):
    def __init__(self,name,carbu,bVitesse,poids,longueur):
        super().__init__(name,carbu,bVitesse)
        self.poids = poids
        self.longueur = longueur

    def seDeplacer(self):
        print(f"Le camion {self.nom} roule au {self.carburant} ,a une boite de vitesse {self.boiteVitesse}, a un poids de {self.poids} et une longueur de {self.longueur}")

c1 = Camion("Turbo22","diesel","automatique",22,2)
c1.seDeplacer()  
$ python3 popo.py 
Le camion Turbo22 roule au diesel ,a une boite de vitesse automatique, a un poids de 22 et une longueur de 2

Dernière modification par beuguissime (Le 29/04/2021, à 19:47)

Hors ligne

#3 Le 29/04/2021, à 20:36

chris7522

Re : [RESOLU]Heritage (python)

Merci de ton aide .
Le message d'erreur était celui-ci :

chris@chris:~/Bureau/Essai$ python3 essai14.py
Traceback (most recent call last):
  File "essai14.py", line 47, in <module>
    c1 = Camion("Turbo22","diesel","automatique",22,2)
  File "essai14.py", line 24, in __init__
    Vehicule.__init__(self,name,carbu,bVitesse)
  File "essai14.py", line 3, in __init__
    self.nom = name
AttributeError: can't set attribute
chris@chris:~/Bureau/Essai$ 

     Pour construire ces classes , j'ai suivi une vidéo sur youtube . Pas facile de s'y retrouver parfois car chacun fait un peu a sa sauce et les vidéos datent un peu .
    J'ai essayé en utilisant super() en gardant le code d'origine et ca compile tout de meme .
    La , j'ai utilisé les property pour me faire la main , mais j'ai pas l'impression que c'est utilisé aussi souvent que ca , en tout cas , pas de facon systematique . Dans quelle situation dois je l'utiliser , car c'est un peu lourd tout ca ?

Hors ligne

#4 Le 29/04/2021, à 21:30

beuguissime

Re : [RESOLU]Heritage (python)

En gardant le code d'origine (message 1) et en changeant Vehicule.__init__(self, a, b, c) par super().__init__(a, b, c), ça ne marche toujours pas chez moi

$ python3 popo.py 
Traceback (most recent call last):
  File "popo.py", line 47, in <module>
    c1 = Camion("Turbo22","diesel","automatique",22,2)
  File "popo.py", line 24, in __init__
    super().__init__(name,carbu,bVitesse)
  File "popo.py", line 3, in __init__
    self.nom = name
AttributeError: can't set attribute


Pour définir un attribut d'une classe, tu peux en effet utiliser une assignation directe de la forme

self.un_attribut = une_valeur

que tu places dans __init__ ou ailleurs en fonction du besoin.

Tu pourrais vouloir en passer par une fonction intermédiaire get() et set() pour que l'utilisateur/rice puisse respectivement obtenir/définir la valeur de l'attribut car par exemple, tu l'empêches de le redéfinir à la volée.

Avec mon exemple du 2, rien ne m'empêche d'écrire

c1 = Camion("Turbo22","diesel","automatique",22,2)
c1.poids = 999999.9999
c1.seDeplacer()  

Si tu as une bonne raison d'empêcher d'écrire c1.poids = truc ou tout simplement, si tu veux prendre l'utilisateur par la main, tu peux le forcer à passer par c1.set_poids(truc) pour changer la valeur de la masse du véhicule. C'est un cas d'usage de property que j'ai vu/essayé. Je ne suis malheureusement pas assez familier avec les property pour en dire beaucoup plus.

Hors ligne

#5 Le 30/04/2021, à 09:04

Compte supprimé

Re : [RESOLU]Heritage (python)

Bonjour,

chris7522 a écrit :

Merci de ton aide .
Le message d'erreur était celui-ci :

chris@chris:~/Bureau/Essai$ python3 essai14.py
Traceback (most recent call last):
  File "essai14.py", line 47, in <module>
    c1 = Camion("Turbo22","diesel","automatique",22,2)
  File "essai14.py", line 24, in __init__
    Vehicule.__init__(self,name,carbu,bVitesse)
  File "essai14.py", line 3, in __init__
    self.nom = name
AttributeError: can't set attribute
chris@chris:~/Bureau/Essai$ 

L'exception est dû au fait que l'attribut name ne dispose pas de setter. https://stackoverflow.com/questions/273 … e/27627094

J'ai essayé en utilisant super() en gardant le code d'origine et ca compile tout de meme .

inutile d'utiliser super(), ta premiére écriture est correcte.

   

La , j'ai utilisé les property pour me faire la main , mais j'ai pas l'impression que c'est utilisé aussi souvent que ca , en tout cas , pas de facon systematique . Dans quelle situation dois je l'utiliser , car c'est un peu lourd tout ca ?

On l'utilise lorsqu'on a besoin de rajouter une couche logique à un attribut afin de le modifier..

#6 Le 30/04/2021, à 11:29

chris7522

Re : [RESOLU]Heritage (python)

Milles merci a tous les deux pour vos solutions et remarques pertinentes , cela m'aide beaucoup a avancer .
Par "couche logique " , tu entends : pseudo protection de l'attribut par encapsulation ?
Bon week-end
smile

Dernière modification par chris7522 (Le 30/04/2021, à 11:37)

Hors ligne

#7 Le 30/04/2021, à 12:01

beuguissime

Re : [RESOLU]Heritage (python)

pseudofab a écrit :

J'ai essayé en utilisant super() en gardant le code d'origine et ca compile tout de meme .

inutile d'utiliser super(), ta premiére écriture est correcte.

C'est mieux d'utiliser super(), non ?
S'il change le nom de la classe parente, il faudra aussi penser à mettre à jour la fonction __init__.
En programmation, quand on peut éviter une répétition, c'est mieux.

Hors ligne

#8 Le 30/04/2021, à 14:05

beuguissime

Re : [RESOLU]Heritage (python)

Je persiste, mais je veux bien que pseudofab me contredise wink, ce que je propose en 2 est la façon pythonique de le faire. C'est la plus claire et la plus concise. Tu devrais employer des getter/setter que lorsque c'est justifié et non pas de façon générale.

Ici, évidemment, si c'est un objectif académique/de découverte, c'est une bonne opportunité pour se frotter aux getter/setter. Et je me rends compte qu'alors ma réponse tape à côté puisque au lieu de corriger le problème que tu rencontres, je t'ai proposé une solution correcte mais qui ignore totalement le sujet. Dans ce cas, il manquait 3 setter dans la classe Vehicule… Ce qui m'a surpris puisque tu ne les avais pas oubliés dans la classe enfant Camion.

Hors ligne

#9 Le 30/04/2021, à 19:31

Compte supprimé

Re : [RESOLU]Heritage (python)

chris7522 a écrit :

Par "couche logique " , tu entends : pseudo protection de l'attribut par encapsulation ?
smile

non,juste le fait modifier l'attribut en fonction d'un traitement effectué dans les méthodes _get, _set. du property  .
Voici ci dessous un cas école ou l'on comprends ce que l'on peut faire des property.

class Temperature2:
    def __init__(self, kelvin=None, celsius=None):
        self.K = 273.16  # kelvin / celsius
        if kelvin is not None:
            self.kelvin = kelvin
        elif celsius is not None:
            self.celsius = celsius
        else:
            self.kelvin = 0
            raise ValueError("Vous devez choisir une unité")
    
    def _get_kelvin(self):
        return self._kelvin

    def _set_kelvin(self, kelvin):
        if kelvin < 0:
            raise ValueError("impossible: kelvin doit être un nombre positif!")
        self._kelvin = kelvin
        
    kelvin = property(_get_kelvin, _set_kelvin)
     
    def _set_celsius(self, celsius):
        # using .kelvin instead of ._kelvin to enforce
        self.kelvin = celsius + self.K

    def _get_celsius(self):
        return self._kelvin - self.K
    
    celsius = property(_get_celsius, _set_celsius)

Ce qui donne:

>>> t = Temperature2(celsius=20)
>>> t.celsius
20.0
>>> t.kelvin
293.16
>>> t.kelvin = 10
>>> t.celsius
-263.16
>>> t.kelvin = -10
Traceback (most recent call last):
  File "<pyshell#13>", line 1, in <module>
    t.kelvin = -10
  File "/home/fab/bidon.py", line 41, in _set_kelvin
    raise ValueError("impossible: kelvin doit être un nombre positif!")
ValueError: impossible: kelvin doit être un nombre positif!
>>> 

@beuguissime: je ne te condirais pas  wink.
d'autant que je suis d'accord.
Pour l'emploi de super() ou non, de mon coté je préfére initialiser les __init__ à la main. C'est plus explicite et l'on en comprend le mécanisme . Je trouve donc cette façon de faire plus pythonique. Le problème avec super(), c'est que ça reste une recette magique pour beaucoup.

#10 Le 30/04/2021, à 23:13

beuguissime

Re : [RESOLU]Heritage (python)

Ça marche ! wink

Hors ligne