9
votes

Écrire une classe qui accepte un rappel en Python?

Je dois écrire une classe qui permet à une sous-classe de définir un attribut avec le nom d'une fonction. Cette fonction doit ensuite être appelable des instances de la classe.

Par exemple, je dis que je dois écrire une classe de fruits où la sous-classe peut passer un message de bienvenue. La classe de fruits doit exposer un attribut print_callback pouvant être défini. P>

mac = Apple()


2 commentaires

J'apprécie les problèmes que vous avez rencontrés avec cette approche et les excellentes solutions ci-dessous. Cependant, cela me semble que vous devez définir print_callback comme méthode (peut-être simplement appelé print_me et obtenir des sous-classes pour le remplacer. Ce serait simple et pythonique. Pour chaque Différent type de print_me , crée une sous-classe différente.


Ma motivation pour la pose de la question était que je voulais sous-classe Google App Moteur de Google.Appengine.ext.db.djangoforms (par exemple comme DF2) pour permettre la dérogation d'un attribut formfield_callback de la même manière que le modelform de Django (Django.Forms.Modelform) . L'idée est que «la classe F (DF2)» pourrait ensuite être utilisée par Standard Django simplement en modifiant la superclasse vers Django.Forms.Modelform. Je ne sais pas pourquoi les auteurs Django ont défini Formfield_Callback en tant qu'attribut.


5 Réponses :


10
votes

Python suppose que toutes les fonctions liées dans un cadre de classe sont des méthodes. Si vous souhaitez les traiter comme des fonctions, vous devez creuser dans leurs attributs pour récupérer l'objet de fonction d'origine:

def __init__(self, *args, **kwargs):
    super(Fruit, self).__init__(*args, **kwargs)

    # The attribute name was changed in Python 3; pick whichever line matches
    # your Python version.
    callback = self.print_callback.im_func  # Python 2
    callback = self.print_callback.__func__ # Python 3

    callback("Message from Fruit: ")


3 commentaires

Ou mieux encore, ajoutez simplement un argument auto à la fonction afin qu'il puisse agir comme une méthode normale.


Selon la question, la définition de rappel ne peut pas être modifiée.


BTW, également à noter, c'est que l'attribut im_func de méthodes a été renommé sur __ func __ à Python 3.x.



2
votes

mis à jour : incorporant Abourget's Suggestion à utiliser staticmethod :

Essayez ceci: xxx


0 commentaires

5
votes

Vous pouvez utiliser directement: xxx

ou: xxx

Dans le premier cas, vous n'obtiendrez qu'un seul paramètre (le original). Dans la seconde, vous recevrez deux paramètres où le premier sera la classe sur laquelle il a été appelé.

J'espère que cela aide et est plus court et moins complexe.


1 commentaires

"Pour être clair, ce code ne peut pas changer, disons que c'est le 3ème code de la partie"



0
votes

Il y a aussi une solution de miteuse avec des métaclasses: xxx

Il manipule la classe avant sa création!


0 commentaires

3
votes

Je cherchais quelque chose de plus comme ça lorsque j'ai trouvé cette question: xxx


0 commentaires