J'initialise une classe avec deux sous-classes en Python à l'aide d'un dictionnaire. Serait-il possible de vérifier une clé dans le dictionnaire au sein de l'init et en fonction du résultat initialiser l'une des deux sous-classes? Par exemple:

Class Pet():
    def __init__(self,dic):
       self.name=dic['name']
       self.age=dic['age']
       if dic['type']=='dog':
          #Initialize a dog which inherits all pet methods with name and age passed onto it 
       elif dic['type']=='cat':
          #Initialize a dog which inherits all pet methods with name and age passed onto it 


    def pet_methods():      
        # a bunch of pet methods that I would like to be inherited


    Class Dog():
       def __init__(self):
          self.dog_attributes=dic['dog_attributes']
    Class Cat():
       def __init__(self):
          self.cat_attributes=dic['cat_attributes']

Quel code peut être utilisé dans l'instruction if / else? Ou existe-t-il une meilleure façon d'organiser le code? Je suis confus car il semble que je veuille appeler un init dans un autre init.

1
user3776598 13 juil. 2015 à 18:23

3 réponses

Meilleure réponse

Bien que cela puisse être possible par la sémantique des classes de python, je dirais que c'est un modèle de conception médiocre et devrait être évité.

En programmation orientée objet, vos classes doivent représenter des divisions entre des parties de vos données et de la logique. Ce que vous faites en ce moment est le couplage la logique / données de la superclasse Pet et de ses sous-classes. Au lieu de cela, vous devez vous efforcer de découpler vos objets autant que possible. Cela simplifie l'interface entre les classes et vous aide à écrire des classes aussi génériques que possible et à utiliser des sous-classes pour implémenter un comportement spécifique.

Dans votre cas, vous devez effectuer l'initialisation de différents types d'animaux domestiques dans les méthodes __init__ des animaux spécifiques. Si vous écrivez votre code de cette façon, il est conceptuellement beaucoup plus facile d'ajouter de nouvelles Pet sous-classes - tout ce que vous devez faire est hériter de Pet et initialiser la sous-classe comme il se doit.

La méthode que vous essayez d'implémenter en ce moment rend beaucoup plus difficile l'implémentation de sous-classes. Un implémenteur devra comprendre quelles variables définir dans la sous-classe pour se connecter au schéma d'initialisation des classes Pet, puis il devra aller dans la source Pet et implémenter de nouvelles fonctionnalités pour initialiser la nouvelle { Type de sous-classe {X2}}. C'est beaucoup plus difficile à faire et nécessite l'édition de plusieurs classes juste pour implémenter une nouvelle sous-classe.

Cette question parle également des problèmes de ce que vous êtes essayer de mettre en œuvre.

1
Community 12 avril 2017 à 07:31

Dans les sous-classes, votre méthode init remplace la méthode init de la superclasse d'origine. Cela fonctionnera bien et est un concept d'importation de programmation orientée OObject. Si vous souhaitez appeler une méthode init à partir de la superclasse, faites super(self). Si vous souhaitez appeler une autre méthode, faites super.method() et incluez tout argument supplémentaire.

1
ytpillai 13 juil. 2015 à 15:28

Ce que vous avez publié n'est pas ce que vous pensez. Dans votre exemple, "Chien" et "Chat" ne sont pas des sous-classes de "Pet", ce sont des classes internes . J'ai posté du code ci-dessous montrant comment vous devez écrire les sous-classes. Pour instancier différentes sous-classes dans votre situation, il est préférable d'utiliser le modèle d'usine que vous pouvez rechercher sur Google et que j'ai inclus comme exemple ci-dessous. J'ai également configuré l'usine pour pouvoir renvoyer le sous-type correct par String, mais c'est une façon laide de faire les choses, donc je vous suggère de ne pas utiliser l'exemple.

class Pet:
    def __init__(self):
        pass

    def method1(self):
        print "Method 1 has been called."

    def method2(self):
        print "Method 2 has been called."

    def yelp(self):
        print "I am yelping"


class Dog(Pet):
    def __init__(self):
        Pet.__init__(self)

    def yelp(self):
        print "I am barking"


class Cat(Pet):
    def __init__(self):
        Pet.__init__(self)

    def yelp(self):
        print "I am meowing"


class PetFactory:
    def __init__(self):
        pass

    def acquire_dog(self):
        return Dog()

    def acquire_cat(self):
        return Cat()

    def acquire_pet_by_name(self, pet_type):
        if pet_type == "dog":
            return Dog()
        elif pet_type == "cat":
            return Cat()

Cela donnera:

>>> pet = Pet()
>>> dog = Dog()
>>> cat = Cat()
>>> dog.yelp()
I am barking
>>> cat.yelp()
I am meowing
>>> pet.yelp()
I am yelping
>>> pet_factory = PetFactory()
>>> pet_factory.acquire_cat().yelp()
I am meowing
>>> pet_factory.acquire_pet_by_name("cat").yelp()
I am meowing
>>> cat.method1()
Method 1 has been called.
>>> dog.method2()
Method 2 has been called.
1
zamhassam 13 juil. 2015 à 15:44