suivant Cette réponse semble que la métaclasse d'une classe peut être modifiée après la définition de la classe en utilisant ce qui suit *: définir une fonction p> me permet d'appliquer un décorateur à une définition de classe similaire, P> class B(object):
__metaclass__ = MyMetaClass
pass
3 Réponses :
Mon résumé de votre question: "J'ai essayé une nouvelle façon délicate de faire une chose, et cela n'a pas bien fonctionné. Devrais-je utiliser la solution simple à la place?" P>
Oui, vous devriez le faire de manière simple. Vous n'avez pas dit pourquoi vous êtes intéressé à inventer une nouvelle façon de le faire. P>
Je me demandais simplement s'il y avait un décorateur équivalent à définir le __ métaclass __ code> dans une définition de classe. Je suppose qu'une autre partie de ma question est que mon "décorateur" a fait semble i> au travail, mais j'ai remarqué que la classe décorée n'a pas
__ métaclass __ code>, donc il y a clairement une différence entre les deux méthodes; Pourquoi est-ce?
La classe n'a pas de Quelle métaclasse à utiliser est normalement déterminée En fait, normal Les classes sont toutes des instances de la métaclass Je n'utiliserais pas votre approche de décorateur. Il obscurcit le fait qu'une métaclasse est impliquée (et laquelle) est toujours une ligne de chaudière, et il est simplement en désordre pour créer une classe à partir des 3 fonctionnalités définissant Lorsque vous faites cela dans Python 2.x: P> __ métaclass __ code> Set d'attribut ... Parce que vous ne le réglez jamais!
__ METACLASS__ code> défini dans un bloc de classe. L'attribut
__ métaclass __ code> n'est pas défini par la métaclasse. Donc, si vous invoquez une métaclasse directement plutôt que de régler
__ métaclass __ code> et de laisser python la figure, alors aucun
__ métaclass __ code> est défini. P>
type code>, donc si la métaclasse définit toujours le
__ métaclass __ code> sur ses instances alors chaque classe em> aurait un
__ METACLASS __ CODE> Attribut (la plupart d'entre eux définis sur
TYPE CODE>). P>
(nom, bases, attributs) code> Seulement pour tirer ces 3 bits de la classe résultante, jeter la classe à l'extérieur et faire une nouvelle classe à partir de ces mêmes 3 bits! p>
attrs = {}
attrs['__metaclass__'] = MyMeta
def __init__(self):
pass
attrs['__init__'] = __init__
A = attrs.get('__metaclass__', type)('A', (object,), attrs)
Certes, je suis un peu en retard à la fête. Cependant, j'ai chuté cela valait la peine d'être ajouté.
Ceci est complètement faisable. Cela étant dit, il y a beaucoup d'autres moyens d'accomplir le même objectif. Toutefois, la solution de décoration, en particulier, permet une évaluation différée ( Il y a une chose délicate que vous puissiez rencontrer si vous construisez simplement la classe sans changer le dictionnaire ou de copier ses attributs. Tout attributs que la classe avait précédemment (avant décoration) semble manquer. Donc, il est absolument essentiel de les copier puis de les modifier, puis que j'ai dans ma solution. P> Personnellement, j'aime pouvoir garder une trace de la manière dont un objet a été enveloppé. Donc, j'ai ajouté l'attribut pour un exemple trivial, prenez les suivants. P> ceci donne le bon résultat ... p> Utilisation du décorateur moins habituel, mais identique ... P> obj = déc (obj) code>), qui utilise
__ métaclass __ code> à l'intérieur de la classe. Dans le style de décorateur typique, ma solution est ci-dessous. P>
__ __ code>, qui n'est pas strictement nécessaire. Il en fait aussi plus que
functools.wraps code> à Python 3 pour les classes. Cependant, cela peut être utile avec l'introspection. De plus,
__ métaclass __ code> est ajouté pour agir davantage comme le cas d'utilisation de la métaclasse normale. P>
|1> Test.passed
|.> True
Si cela est utile, faites-le dans le paquet Metawrap CODE> sur PYPI. Les commentaires sur le repo GitHub sont les bienvenus. :) ref: pypi.org/project/metawrap ref: GITUB.COM/JAKIRKHAM/METAWRAP