2009-11-22 4 views

Répondre

34

Les décorateurs sont beaucoup, beaucoup plus simples et plus limités - et devraient donc être préférés chaque fois que l'effet désiré peut être atteint avec une métaclasse ou un décorateur de classe.

Tout ce que vous pouvez faire avec un décorateur de classe, vous pouvez bien sûr faire avec une métaclasse personnalisée (appliquez simplement la fonctionnalité de la "fonction décorateur", c'est-à-dire celle qui prend un objet de classe et le modifie) de la métaclasse __new__ ou __init__ qui fait l'objet de classe! -).

Il y a beaucoup de choses que vous pouvez faire dans une métaclasse personnalisée mais pas dans un décorateur (à moins que le décorateur génère et applique une métaclasse personnalisée, bien sûr - mais c'est tricher; -) ... et même alors, dans Python 3, il y a des choses que vous ne pouvez faire qu'avec une métaclasse personnalisée, pas après coup ... mais c'est une sous-niche assez avancée de votre question, alors laissez-moi vous donner des exemples plus simples).

Par exemple, supposons que vous voulez faire un objet de classe X telle que print X (ou en Python 3 print(X) bien sûr ;-) affiche peekaboo!. Vous ne pouvez pas le faire sans une métaclasse personnalisée, car le remplacement de la métaclasse __str__ est l'acteur crucial ici, c'est-à-dire que vous avez besoin d'un def __str__(cls): return "peekaboo!" dans la métaclasse personnalisée de la classe X. Il en va de même pour toutes les méthodes magiques, c'est-à-dire pour toutes les opérations appliquées à l'objet de classe lui-même (par opposition aux instances qui utilisent des méthodes magiques telles que définies dans la classe - les opérations sur l'objet de classe lui-même utilisent des méthodes magiques telles que définies dans la métaclasse).

+0

réponse intéressante d'éminent compatriote =) – gpilotino

+0

Salut gino, toujours particulièrement heureux d'aider un compatriote bien sûr ;-). –

+6

Eh bien .. ça fait 4 ans et j'ai trouvé cette question chez google. Je veux juste prendre note de votre exemple. J'ai défini un décorateur 'foo (cls)' qui a 2 instructions: 'cls .__ str__ = lambda self:" peekaboo! "' Et juste après cela 'return cls', et cela a fonctionné - j'ai réglé le' méthode __str__' d'une certaine classe avec le décorateur plutôt qu'avec une métaclasse compliquée .. Je voulais juste le noter, et peut-être obtenir un commentaire pour savoir si quelque chose me manque. – rboy

Questions connexes