CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

Explication ClasseParente.__init__(self,x,x) sur Python

naxcda
naxcda
Niveau 7
01 août 2021 à 19:21:39

Salut,

J'apprend à utiliser python avec le livre "Apprendre python" de Gerard Swinner, je suis au passage des classes, tout est a peu près clair sauf la méthode __init__ des classes dérivées faisant référence à la classe parente

Un exemple de ce dont je parle :

class CompteBancaire(object):
....def __init__(self, nom = "Dupond" , somme = 1000):
........self.nom= nom
........self.somme = somme

Ici, si je crée un objet test = CompteBancaire() sans donner d'argument dans les parenthèses, il aura automatiquement le nom et la somme définie comme Dupond et 1000

Mais si je crée une classe dérivée par exemple :

class CompteEpargne(CompteBancaire):
.... def __init__(self, nom, solde, taux):       
........CompteBancaire.__init__(self, nom, solde) 
........self.taux = 1.003

Et que je crée un object test1 = CompteEpargne() , j'ai un message d'erreur " TypeError: __init__() missing 2 required positional arguments: 'nom' and 'solde'" là où je voudrais que Test1 ait comme parametre nom = Dupond, somme = 1000 et taux = 1.003
Le programme ne fonctionnant qu'en donnant deux arguments a "test1" par exemple "Levalier" et "12"

Y a t il un moyen d'organiser son programme pour pouvoir appeler une instance d'une classe dérivée sans argument (comme ici dans l'exemple) tout en ayant les paramètres de la classe parente par défaut ?

De manière plus générale, je ne comprend pas comment fonctionne l'usage de ClasseParente.__init__(self, parametre1, parametreX) , comme cet autre exemple du livre :
https://image.noelshack.com/fichiers/2021/30/7/1627838083-sw.png

Je comprend pas bien comment Rectangle.__init__(self,coin,cote,cote) permet a la classe rectangle de récupérer des objets qui lui sont inconnus

Si quelqu'un pourrait m'expliquer ou aurait un lien vers une explication a me fournir :ok:

Message édité le 01 août 2021 à 19:22:26 par naxcda
neytsumi
neytsumi
Niveau 12
02 août 2021 à 22:41:07

Plusieurs choses, on va commencer avec ta méthode __init__ du compte bancaire :-)

class CompteEpargne(CompteBancaire):
.... def __init__(self, nom, solde, taux):
 

Tu l'as vu dans ton cours mais c'est à travers la méthode __init__ que tu vas pouvoir construire ton objet. Hors ici (sans même regarder le reste) tu imposes que pour construire un objet CompteEpargne, tu dois lui donner un nom, un solde et un taux. Il n'y a aucun argument par défaut, donc tu es obligé de les donner à la construction de l'objet comme tu l'as expérimenté.

Si tu veux utiliser les paramètres par défaut de la classe parente de la quelle tu dérives, tu n'as pas besoin de les rendre obligatoire dans ton objet fils :
def __init__(self, taux): ....CompteBancaire.__init__(self) // pas sûr pour le self

Ainsi test1 = CompteEpargner(1.003) te donnera nom=Dupond, somme=1000, taux=1.003

Tu peux mettre un paramètre par défaut à "taux" si tu veux éviter de devoir le préciser à la construction (comme pour ta classe parente) avec par exemple : def __init__(self, taux=1.003):

Si tu veux que ta classe CompteEpargne ait des paramètres par défaut différents de ceux de CompteBancire, tu peux redéfinir les paramètres par défaut (override) avec la définition suivante :
class CompteEpargne(CompteBancaire): .... def __init__(self, nom=toto, solde=2000, taux=1.003):

Ainsi tu vas pouvoir faire toutes les déclarations suivantes:
compte1 = CompteEpargne() // nom=toto, solde=2000, taux=1.003 compte2 = CompteEpargne(taux=1.5) // pareil mais taux = 1.5 compte3 = CompteEpargne(nom="tata") // nom=tata, solde=2000, taux=1.003 compte4 = CompteEpargne("titi", 5000, 2) // nom=titi, solde = 5000, taux=2 etc.

Message édité le 02 août 2021 à 22:44:32 par neytsumi
neytsumi
neytsumi
Niveau 12
02 août 2021 à 22:48:13

J'y pense mais la syntaxe recommandée pour appeler le constructeur de la classe parente ce serait plutôt ça (en Python 3):
def __init__(self, taux): ....super().__init__() # pas besoin du self dans ce cas-là

D'ailleurs tu peux appeler toutes les méthodes parentes de ta classe mère depuis ta classe fille avec la fonction super().

Message édité le 02 août 2021 à 22:49:02 par neytsumi
neytsumi
neytsumi
Niveau 12
02 août 2021 à 23:00:29

"De manière plus générale, je ne comprend pas comment fonctionne l'usage de ClasseParente.__init__(self, parametre1, parametreX)"

Je te réponds rapidement pour celle-là (si qqn d'autre veut développer :-))
Quand tu as une classe fille B qui dérive d'une classe parente A, il faut bien comprendre que B est une classe de type A auquelle on a rajouté des attributs et des méthodes. Donc si tu veux construire B tu as besoin de d'abord construire A, puis ensuite de spécifier la construction propre à l'objet B. Et pour construire A il faut utiliser son constructeur. Le super().__init__ permet d'appeler le constructeur de la classe A et tu dois lui donner les paramètres qu'il a besoin pour construire l'objet A, comme tu ferais si tu déclarais directement un objet A sans passer par B.

neytsumi
neytsumi
Niveau 12
02 août 2021 à 23:15:16

Si tu veux que ta classe CompteEpargne ait des paramètres par défaut différents de ceux de CompteBancire, tu peux redéfinir les paramètres par défaut (override) avec la définition suivante :
class CompteEpargne(CompteBancaire): .... def __init__(self, nom=toto, solde=2000, taux=1.003):

Ainsi tu vas pouvoir faire toutes les déclarations suivantes:
compte1 = CompteEpargne() // nom=toto, solde=2000, taux=1.003 compte2 = CompteEpargne(taux=1.5) // pareil mais taux = 1.5 compte3 = CompteEpargne(nom="tata") // nom=tata, solde=2000, taux=1.003 compte4 = CompteEpargne("titi", 5000, 2) // nom=titi, solde = 5000, taux=2 etc.

Je peux pas éditer donc je réponds là, si tu veux un tel comportement il faut cette définition :

class CompteEpargne(CompteBancaire):
.... def __init__(self, nom=toto, solde=2000, taux=1.003):
........super.__init__(nom, solde)

Si tu veux que tes paramètres par défaut de ta classe parente servent à quelque chose, tu peux faire ça :

class CompteEpargne(CompteBancaire):
.... def __init__(self, nom=toto, solde=2000, taux=1.003):
........super.__init__()

Là tes paramètres par défaut de CompteEpargne ne servent plus à rien, mais tu peux écraser ceux du parent si ça te chante, par exemple :

 class CompteEpargne(CompteBancaire):
.... def __init__(self, nom=toto, solde=2000, taux=1.003):
........super.__init__(nom, solde)
........self.nom = nom

test = CompteEpargne() // nom=toto, solde=1000, taux=1.003

Mais bon tu perds un peu l'intérêt de l'héritage et des paramètres par défaut si tu dois écrire ce genre de code :hap:

Je m'arrête là pour ce soir, désolé pour le multi-post, j'espère ne pas dire trop de conneries :noel:

Message édité le 02 août 2021 à 23:15:59 par neytsumi
naxcda
naxcda
Niveau 7
03 août 2021 à 23:26:31

Le 02 août 2021 à 23:00:29 :
"De manière plus générale, je ne comprend pas comment fonctionne l'usage de ClasseParente.__init__(self, parametre1, parametreX)"

Je te réponds rapidement pour celle-là (si qqn d'autre veut développer :-))
Quand tu as une classe fille B qui dérive d'une classe parente A, il faut bien comprendre que B est une classe de type A auquelle on a rajouté des attributs et des méthodes. Donc si tu veux construire B tu as besoin de d'abord construire A, puis ensuite de spécifier la construction propre à l'objet B. Et pour construire A il faut utiliser son constructeur. Le super().__init__ permet d'appeler le constructeur de la classe A et tu dois lui donner les paramètres qu'il a besoin pour construire l'objet A, comme tu ferais si tu déclarais directement un objet A sans passer par B.

Donc si je comprend bien, la méthode super().__init__ re-initialise les paramètres de la classe parente à travers l'objet fils, pour qu'un parametre parent "Dupond" devienne par exemple "Brunard" lorsqu'appellé par la classe fille ?

Merci pour les explication détaillées c'est beaucoup plus clair ! En fait c'était tout bete, "Si tu veux utiliser les paramètres par défaut de la classe parente de la quelle tu dérives, tu n'as pas besoin de les rendre obligatoire dans ton objet fils" , c'est le meme fonctionnement que pour une fonction classique

Pour le dernier code que tu montre :
class CompteEpargne(CompteBancaire):
.... def __init__(self, nom=toto, solde=2000, taux=1.003):
........super.__init__(nom, solde)
........self.nom = nom

J'imagine que tu voulais ecrire self.taux = taux à la dernière ligne ? Car sinon j'ai un message d'erreur du fait que "taux" n'est pas définis sur cette classe

Sous forums
  • Aide à l'achat Mac
  • Création de Jeux
  • Linux
  • Création de sites web
  • Programmation
  • Internet
  • Steam Deck
  • Macintosh
  • Hardware
La vidéo du moment