2017-09-02 8 views
2

J'essaie de comprendre comment créer une sous-classe qui ignore ou n'inclut pas d'attribut que la classe parente utilise __init__ et super() mais je n'arrive pas à envelopper ma tête l'entoure.Ignorer un paramètre lors du remplacement d'une super-classe en Python

J'ai essayé de créer un héritage simple avec les codes suivants:

class Animal: 
    def __init__(self, name, age, sound, **kwargs): 
     self.name = name 
     self.age = age 
     self.sound = sound 


     for key, value in kwargs.items(): 
      setattr(self, key, value) 

class Dog(Animal): 
    def __init__(self, name, age, sound, *args, **kwargs): 
     super().__init__(name, age, sound, **kwargs) 


class Lion(Animal): 
    def __init__(self, age, sound, *args, **kwargs): 
     super().__init__(age, sound, **kwargs) 

Ci-dessous, j'ai essayé d'imprimer les attributs de base/informations pour chaque sous-classe (Dog et Lion). Leurs paramètres communs sont name, age et sound qui sont tous présents dans ma classe Dog (j'ai également ajouté pet et breed).

Quant à la classe Lion car il n'a pas besoin de nom (car il vit habituellement dans la nature) J'ai essayé de sauter le paramètre name donc je ne mentionnaient pas dans __init__ et super().

Quand je lance le fichier, il obtient un

TypeError: __init__() missing 1 required positional argument: 'sound'.

dog = Dog('Lucky', 6, 'Arf! Arf!', pet=True, breed='Shih Tzu') 
lion = Lion(10, 'Roar!', wild=True) 
print("===Dog===") 
print("Name: {}".format(dog.name)) 
print("Age: {}".format(dog.age)) 
print(dog.sound) 

print("\n===Lion===")  
print("Age: {}".format(lion.age)) 
print(lion.sound) 

donc j'essayé de contourner les codes et mis sound="" dans la classe Animal. Je n'ai pas obtenu l'erreur cette fois mais je n'ai pas obtenu la bonne sortie.

===Dog=== 
Name: Lucky 
Age: 6 
Arf! Arf! 

===Lion=== 
Age: Roar! 

Je veux que le Lion d'avoir les bons attributs en place comme le Dog sauf le nom qui est pas nécessaire.

Y at-il quelque chose qui me manque dans le code?

+1

L'héritage est un ** est une relation ** . Si vous ne voulez pas que tous les 'Animal's aient des' name's, ne leur donnez pas un 'nom'. –

Répondre

1

La solution simple serait simplement de laisser passer un name vide, par ex. "" ou None. C'est parce que vous ne pouvez pas sauter les arguments si vous les avez rendus obligatoires! Comme vous l'avez fait dans le __init__ de votre Animal.

class Lion(Animal): 
    def __init__(self, age, sound, *args, **kwargs): 
     super().__init__("", age, sound, **kwargs) 

Cependant peut-être une meilleure solution serait de faire name un paramètre optionnel, car un Animal peut avoir un nom, mais ne nécessite pas un nom. Rappelez-vous toujours que les classes abstraites tentent de « concepts réels »:

class Animal: 
    def __init__(self, age, sound, **kwargs): 
     self.age = age 
     self.sound = sound 
     for key, value in kwargs.items(): 
      setattr(self, key, value) 

class Dog(Animal): 
    def __init__(self, age, sound, *args, **kwargs): 
     super().__init__(age, sound, **kwargs) 


class Lion(Animal): 
    def __init__(self, age, sound, *args, **kwargs): 
     super().__init__(age, sound, **kwargs) 

dog = Dog(6, 'Arf! Arf!', name='Lucky', pet=True, breed='Shih Tzu') 
lion = Lion(10, 'Roar!', wild=True) 
print("===Dog===") 
print("Name: {}".format(dog.name)) 
print("Age: {}".format(dog.age)) 
print(dog.sound) 

print("\n===Lion===")  
print("Age: {}".format(lion.age)) 
print(lion.sound) 

Les deux approches donnent le bon résultat (pour autant que je peux voir):

===Dog=== 
Name: Lucky 
Age: 6 
Arf! Arf! 

===Lion=== 
Age: 10 
Roar!