J'essaie de faire quelque chose comme ces décorateurs de signaux proposés . En plus d'avoir un décorateur qui relie la méthode décorée à un signal (avec l'expéditeur du signal comme argument du décorateur), j'aimerais utiliser le décorateur sur des méthodes de classe.
J'aimerais utiliser le décorateur comme Donc: p> le décorateur est: p> L'erreur que je reçois quand je le fais est: p>
File "/Library/Python/2.6/site-packages//lib/python2.6/site-packages/django/dispatch/dispatcher.py", line 78, in connect
AssertionError: Signal receivers must be callable.
3 Réponses :
Ce n'est pas clair de votre code exemple, je vous demanderais donc si l'auditeur de signal doit être un Une autre option peut être d'utiliser une deuxième méthode pour écouter le signal et déléguer l'appel au @classmethod code>? C'est à dire. Une méthode régulière sera-t-elle (puis d'utiliser
auto .__ classe __ code> si vous avez toujours besoin d'accéder à la classe elle-même)? Cela doit-il être une méthode du tout (pouvez-vous simplement utiliser une fonction)?
@classmethod code> : p>
Merci je pense que je vais aller avec une solution que quelqu'un a suggéré une autre version de cette question: décorateurs de classe. Le décorateur de classe peut créer la connexion de signal après la charge de la classe entière et cela évite le problème de ne pas pouvoir accéder directement à la méthode de la classe. Stackoverflow.com/Questtions/2366713/...
Pourriez-vous en faire un @StaticMethod à la place? De cette façon, vous pouvez simplement échanger l'ordre des décorateurs.
class ModelA(Model): @staticmethod @connect.post_save(ModelB) def observe_model_b_saved(sender, instance, created, **kwargs): # do some stuff pass
Merci, mais cette solution ne fonctionnera pas pour moi car dans les méthodes que je dépends de l'accès à la classe de manière dynamique afin de récupérer des membres qui ont peut-être été surchargé. Par exemple. La superclasse définit une méthode qui repose sur un attribut, mais la sous-classe surcharge l'attribut. J'ai besoin de l'attribut surchargé et non de celui qui vient de nommer explicitement la classe par nom.
Basé sur la réponse de Matt, le tour @StaticMethod a fonctionné pour moi. Vous pouvez utiliser une chaîne pour faire référence à un modèle non concrètement.
class Foo(Model): @staticmethod @receiver(models.signals.post_save, sender='someappname.Foo') def post_save(sender, instance, created, **kwargs): print 'IN POST SAVE', sender, instance.id, created
Est-ce que cela fonctionne si vous échangez l'ordre de @ClassMethod et @Connect?
Non maintenant, je reçois: "Observer_model_b_saved () prend exactement 4 arguments non clés (0 donné)". Qu'est-ce que ça veut dire?