2011-07-10 1 views
0

J'ai donc une Superclasse (que j'appellerai pour simplifier), Mammal, dont les classes Dog, Monkey et Bear héritent des méthodes. Certaines méthodes héritées renvoient un objet qui doit être de la même classe que celle à laquelle il est appelé. Par exemple, Dog.find(...) doit renvoyer des objets Chien. Mais parce que la méthode find() est héritée de Mammal, la méthode ne peut pas être codée explicitement return Dog(...). Il doit être capable de renvoyer des objets Chien, Singe, Ours ou Mammifère, en fonction de la valeur self.__class__.__name__.Renvoyer un objet basé sur __class __.__ name__ en Python

Je l'ai réalisé avec return eval(self.__class__.__name__)(...), mais je préfère éviter d'utiliser eval. Y a-t-il un meilleur moyen?

+0

Pourquoi exactement voulez-vous demander à un chien afin de trouver un autre chien? Quel est le processus par lequel la valeur de retour est déterminée? (Est-ce que 'trouver' est vraiment un nom raisonnable pour la méthode?) –

+0

C'est un bon point. Je suis d'accord c'est un peu gênant. C'est fondamentalement un modèle d'un framework MVC. Je peux instancier des objets Chien à partir des lignes d'une table DB, faire des choses comme 'dog.name = 'Rex'' puis' dog.save() 'pour le mettre à jour dans la table. Cela me laisse besoin d'une classe qui peut renvoyer des objets Chien en fonction des conditions de recherche, mais j'ai l'impression que c'est trop spécial pour que la classe de l'encapsuleur DB puisse le faire. Je ne suis pas le meilleur en design de classe. – nren

Répondre

3

Juste essayer return self.__class__()

+0

Ok ça marche. Je ne sais pas pourquoi je n'y ai pas pensé. Merci. – nren

2

Utilisez un classmethod pour faire une usine:

class Mammal(object): 

    @classmethod 
    def new(cls, *args, **kwds): 
     return cls(*args, **kwds) 

class Dog(Mammal): 

    def find(self): 
     return self.new() 

>>> d = Dog() 
>>> d2 = d.find() 
>>> type(d2) 
<class '__main__.Dog'> 
+0

Ne connaissait pas @classmethod. Je vais garder cela à l'esprit. L'autre réponse correspond mieux à ce que j'ai déjà, mais je vais essayer la prochaine fois. – nren

+0

@nren Oui, mais cela correspond beaucoup mieux à ma compréhension de ce que vous essayez vraiment de faire :) –

Questions connexes