Je suis revenu à mon clos (système d'objet LISP commun) pour cette question abstraite.
J'augmente la question à clarifier: em> p> Il me semble qu'un décorateur de python est une sorte de méthode "autour" à Clos. p> de ce que je me souviens, une méthode "autour" à Clos est une méthode / fonction qui enveloppe la méthode / la fonction principale du même nom. Il traverse également les sous-classes de haut en bas. EM> Voici une syntaxe (je viens d'attraper mon livre). P> toutes ces méthodes em> Il peut y avoir des méthodes avant et après trop (que je jette une complétude) em> : p> et enfin la méthode autour (remarquez ici que cette méthode semblait être comme un décorateur) em>: p> Je pense que la sortie serait: p> J'ai toujours utilisé cette compréhension des classes et de leurs méthodes comme point de référence pour le développement de code. et malheureusement, peu de langues semblent aller aussi loin avec leur paramétrage et leur puissance de méthode. EM> P> Je suis assez nouveau à Python et j'essaie de voir comment les décorateurs s'intégrent. Ils semblent un Petit lâche dans celui qu'un décorateur peut être une fonction complètement externe qui a pourtant la capacité de manipuler des informations dans les informations d'appel et même de modifier les variables d'instance et de classe de l'objet appelées, et de plus en plus qu'il semble préformer le rôle de la méthode autour comme indiqué ici. Mais j'espérais que quelqu'un puisse aider à expliquer la relation entre les décorateurs et autour des méthodes em>. Je pensais que quelqu'un aimerait vraiment que l'occasion de le faire. P> Qu'est-ce qui rend plus puissant pour moi, c'est que vous pouvez avoir plusieurs héritages avec ces méthodes. Ainsi, une classe peut être constituée de superclasses contenant des fonctionnalités et des attributs distincts qui se manipulent. Ainsi, une méthode autour de l'une des superclasses pourrait terminer le débit (si «appel-next-méthode» n'est pas terminée), comme la façon dont un décorateur peut apparemment fonctionner. Est-ce que c'est la même chose qu'un décorateur ou différent? Dans une méthode autour, vous passez dans les mêmes arguments, mais à un décorateur, vous passez dans la "fonction" dans une définition stricte qui est augmentée. Mais le résultat est le même? Strong> p> Merci beaucoup! Peut-être que quelqu'un pourrait montrer l'approximation de ce qui précède à Python.
Donc, le problème ne consiste pas à mettre en œuvre les méthodes de clos de Python, mais montrant la manière dont Python se rapproche de ce système de manière pythonique. Ou montrant comment Python est en fait meilleur que cela. Em> p> C'est plus du genre d'exemple que je pensais: em> p> Si une instance de triangle a visible = FALSE, alors le rendu: autour de la méthode principale du triangle. em> p> en d'autres termes le La chaîne d'appel de la méthode de rendu est (a) rendue: autour, b) Triangle primaire, (c) terminer le rendement: autour de. Si Triangle avait une méthode: après la méthode, elle serait appelée après primaire, puis la méthode autour de la finition terminée. Em> p> Je comprends les difficultés d'utilisation de l'héritage par rapport à la création de modèles de conception plus récents Mais ici, j'essaie de combler mes connaissances. S'il y a un modèle de conception qui correspond aux décorateurs (plus précisément que le modèle de conception "décorateur"), ce serait formidable de comprendre également. Em> p> Je suis Obtenir la suspension des décorateurs. Mais je voulais présenter où je suis en train d'essayer d'imiter la traversée de la méthode de fermeture. Tout le monde m'a inspiré à l'essayer depuis que j'ai le livre et je me souviens bien de ça. Merci à tous pour toutes les grandes suggestions, ils sont tous un morceau du puzzle. En termes de mise en œuvre de la structure réelle dans un seul décorateur, se rapprochera et c'est ce qui a fonctionné pour le déplacer vers l'avant avec la découverte de la méthode dynamique (voir ci-dessous). J'ai créé un seul décorateur qui fait ce que je recherche et peut fonctionner sur n'importe quelle classe. Je suis sûr que cela pourrait être plus propre et il y a un problème que cela ne cherche que sur une superclasse et que cela fait des méthodes étrangement, mais cela fonctionne. P> Ceci Strike> serait à l'intérieur d'une classe: p> Fait appeler la méthode suivante. Strike> P> Conclusions h1>
Python 2.6.4 (r264:75706, Mar 1 2010, 12:29:19)
[GCC 4.2.1 (Apple Inc. build 5646) (dot 1)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import cw
>>> s= cw.subclass()
>>> s.helloworld()
Sub Around Start
Aound Start
Sub Before
Baseclass Before
Hello Sub World Fooey 2 barrey 7
Baseclass After Fooey Now 4
Sub After
Around End
Sub Around End
>>> s.helloworld()
Sub Around Start
Aound Start
Sub Before
Baseclass Before
Hello Sub World Fooey 5 barrey 8
Baseclass After Fooey Now 7
Sub After
Around End
Sub Around End
>>> s.helloworld()
Sub Around Start
Aound Start
Sub Before
Baseclass Before
Hello Sub World Fooey 8 barrey 9
Baseclass After Fooey Now 10
Sub After
Around End
Sub Around End
>>> s.helloworld()
Sub Around Start
>>Hey Barrey too big!
Sub Around End
>>> s.helloworld()
Sub Around Start
Aound Start
>>FOOEY IS TOO BIG!!!
Around End
Sub Around End
>>> s.helloworld()
Sub Around Start
Aound Start
Sub Before
Baseclass Before
Hello Sub World Fooey -9 barrey -6
Baseclass After Fooey Now -7
Sub After
Around End
Sub Around End
>>> s.helloworld()
Sub Around Start
Aound Start
Sub Before
Baseclass Before
Hello Sub World Fooey -6 barrey -5
Baseclass After Fooey Now -4
Sub After
Around End
Sub Around End
>>> s.helloworld()
Sub Around Start
Aound Start
Sub Before
Baseclass Before
Hello Sub World Fooey -3 barrey -4
Baseclass After Fooey Now -1
Sub After
Around End
Sub Around End
>>> b = cw.baseclass()
>>> b.helloworld()
Aound Start
Baseclass Before
Am I really so wee Before? This method is not called on subclass but should be
Hello World
Baseclass After Fooey Now 5
Around End
>>> b.helloworld()
Aound Start
Baseclass Before
Am I really so wee Before? This method is not called on subclass but should be
Hello World
Baseclass After Fooey Now 9
Around End
>>> b.helloworld()
Aound Start
Baseclass Before
Am I really so wee Before? This method is not called on subclass but should be
Hello World
Baseclass After Fooey Now 13
Around End
>>> b.helloworld()
Aound Start
>>FOOEY IS TOO BIG!!!
Around End
>>> b.helloworld()
Aound Start
Baseclass Before
Am I really so wee Before? This method is not called on subclass but should be
Hello World
Baseclass After Fooey Now -6
Around End
4 Réponses :
Voici une mise en œuvre rapide et sale grève> une implémentation légèrement meilleure (maintenant avec la méthode autour, espérons-le, dans les bons endroits), à l'aide de décorateurs appelant Les décorateurs dans ce cas peuvent être un peu déroutant, car il y a deux em> imbriqué Fonctions impliquées dans chaque, plutôt que la seule fonction imbriquée dans beaucoup de décorateurs. p> Ce n'est peut-être pas aussi élégant que la version proche (et je risquerais de manquer certaines de ses fonctionnalités), mais il semble faire ce que vous voulez. p> p> fn () code> résulte de la présente: p>
@Will, merci pour l'exemple et l'exemple révisé! Je pense que cela va certainement m'aider à ajuster ma cartographie cognitive de la programmation pour inclure cette construction! Maintenant, je vais l'analyser plusieurs fois et voir si ça va s'asseoir dans mon cerveau.
En principe, ce n'est pas loin, mais vous n'avez pas manipulé des exceptions ni la manière dont autour de code> est censé pouvoir également poster des résultats post-traiter. Pas impossible de travailler, mais un peu désordonné. (Vous pouvez implémenter
avant code> et
après code> en termes de
autour de code>, si cela facilite la tâche ...)
Remarque pour la perspective Close: Dans une hiérarchie de classe, la méthode sur laquelle: autour de la classe est appelée en premier (ce qui signifie que l'objet d'instance: sur la méthode). Il monte alors à la superclasse pour appeler la prochaine méthode. Il fait alors la même chose pour: avant de commencer avec la plus spécifique à nouveau. Ensuite, il appelle la méthode principale. Puis le plus spécifique: après des méthodes. Une fois que cela joue, il se déplacerait dans des méthodes autour des méthodes qui avaient un code après la méthode appelée. (Cela diffère de ce qui précède en ce que les "Befores" sont appelés avant les méthodes autour. Je ne sais pas encore les sous-classes.)
@Donal & @ijames, ouais, j'étais sûr que cette mise en œuvre pâlirait par rapport à la mise en œuvre de Clos Clos. J'espérais simplement que cela illustrerait une approche pour utiliser des décorateurs pour accomplir quelque chose de similaire dans le principal (comme vous l'avez souligné). Hors de curiosité, comment vous attendriez-vous des exceptions à traiter par ces décorateurs et comment la méthode autour de pouvoir poster les résultats?
Et je mettez à jour mon exemple pour appeler les fonctions autour du bon endroit, je pense. C'était juste une surveillance stupide de ma part.
Votre méthode autour de code> ne capture pas tout à fait l'essence de ce qui est capable de. Voir mon exemple ci-dessous. Un rappel peut être transmis à la fonction de décoration qui exécute la fonction exactement où vous souhaitez exécuter. Comme Donal Fellows a dit, vous pouvez implémenter
avant code> et
après code> en termes de
autour de code>
@Donal, à droite, il semble que un décorateur aussi peut également gérer le post-traitement en plus du pré-traitement et peut même sauter "appel-méthode appelant" qui, avec des décorateurs, est de ne pas renvoyer aucun aspect de la méthode d'origine. ? Je pense que des exceptions sont locales aux fonctions individuelles. La commande d'exécution n'est donc pas affectée par un cadre d'exception. Des exceptions particulières pourraient modifier le flux de méthodes autour, mais ne pouvaient rien faire avant et après des méthodes. D'après ce que je peux dire, ce type de fragment de fonction (avant et après) ne fait pas partie de Python.
Peut-être que c'est des pommes et des oranges ici? Un décorateur est une classe complètement séparée de la chose décorée. Alors qu'une méthode autour est une méthode polymorphe de la même classe ou de la même classe ou de la sous-classe. Alors sont-ils simplement trop différents pour comparer?
Ok, je commence à avoir une compréhension plus profonde ici. Question sur appelable et instanciation. Question appelable d'abord. Premièrement, que si ces méthodes sont vérifiées n'étaient pas encore appelables? Étant donné que l'emballage semble être une macro, le "appelable" est appelé tôt. Et si les méthodes ont souligné n'existent pas?
En outre, j'essaie d'envisager ce qui précède comme une classe. Donc, au lieu d'avoir ces méthodes flottant là-bas, ils sont dans une classe. Et au lieu d'avoir absolument nommé des méthodes, elles sont éteintes de la méthode principale. Donc, la méthode helloworld () serait accompagnée de def helloworld_before (), helloworld_after () et helloworld_arond (). Hmmm je pense que je suis proche. Je cherche un moyen d'utiliser getattr (instance, Func .__ Nom__ + "_Brefore) ou quelque chose comme ça pour que l'enveloppe / décorateur fait tout ...
Je ne suis pas sûr de comprendre : autour de code>,
: avant code> et
: après code> très bien, mais c'est quelque chose comme ça que tu es ce que tu es Vous recherchez?
# Enter around
# Before
# Hello World
# After
# Exit around around
Outre les multiples classes, cela capture un aspect de la capacité de ferme qui est un flux d'exécution. Mais il y a quelques problèmes que je vois. Tout d'abord, c'est que seule la méthode principale la plus spécifique (FOO's Helloworld) devrait être appelée. Donc, je penserais que c'est: autour, avant, foo, après. Mais la façon dont vous avez représenté autour de vous, comparé à l'avant et après nous rapprocher, et il démontre la capacité de traverser l'arbre de héritage. Mais pourrait-il être fait tout dans une classe? Et comment cette méthode se compare-t-elle à un décorateur Python Python? Merci!
Vous pouvez mettre en œuvre quelque chose de similaire. Will était sur la bonne voie, mais il semble que "appel-next-méthode" est assez crucial à l'utilisation de "autour", qui peut être mise en œuvre comme telle: ceci produit exactement la même sortie que la vôtre, avec des constructions raisonnablement similaires. Faites attention à l'ordre que vous décorez la fonction. P> p>
J'existe en revue le tutoriel ici: Stackoverflow.com/questions/739654/.../ A> Nice! J'ai l'impression que je peux avoir des décorateurs dans une classe. Est-ce vrai?
Je ne sais pas exactement ce que vous demandez, mais la réponse est oui :) Vous pouvez décorer des méthodes, vous pouvez utiliser des méthodes telles que des décorateurs, et vous pouvez décorer des classes, à partir de 2,6 (où votre classe est transmise à la fonction de décoration pour effectuer des modifications. des définitions de classe).
Oui, je l'ai eu. Voir ma conclusion ci-dessus. Je pense que c'est une tresse d'un "module" où il contient un décorateur et une classe et le décorateur décore les méthodes de la classe. J'ai également fourni des échantillons de sortie. Laissez-moi savoir ce que vous pensez! Vers le vôtre ci-dessus, remarquez comment j'ai un décorateur qui cherche tout avant, après, autour de méthodes s'ils existent pour la méthode principale, y compris les méthodes de la superclasse. Ce n'est pas parfait, mais c'est un premier passage à la notion.
Inspiré de la question originale et de tout ce que divers brouillons, j'ai mis en œuvre de près / après / après les méthodes auxiliaires strong> Python Module. P>
Je l'ai fait
Super () code> fonction intégrée forte>, li>
Je suis excité de jeter un coup d'oeil à ça!
Je suis heureux que les autres s'attaquent à votre question directe, mais cette phrase s'en tient à sortir: "J'ai toujours utilisé cette compréhension des classes et de leurs méthodes comme point de référence pour développer le code". Cela me frappe comme un moyen très étrange d'approcher OO. Si vous envisagez d'encapsulation, de sous-classement, etc. En termes de décorateurs et de «avant» et de «après», je vous suggérerais de manière aussi poliment que vous avez une autre chose à aller sur les concepts. De tels décorateurs inhabituels devraient apparaître très rarement, le cas échéant, dans une architecture typique de OO.
Merci dedthinking. J'ai réalisé, examiner les réponses ci-dessous (travaillant toujours sur la compréhension des décorateurs, en particulier dans Django, et quand les utiliser), qu'il y a un autre élément de l'image ci-dessus que je n'avais pas inclus sur Clos. Je vais éditer ce qui précède pour clarifier ce que sont ces méthodes. Je pense que ça va aussi secouer les réponses ci-dessous. Fondamentalement, au ferme toutes ces méthodes définies ci-dessus font partie d'une seule classe. Donc, dans ce cas de base, ces méthodes pourraient être représentées par une méthode / une fonction. Ce n'est que lorsque la sous-classement est intéressante.
Ok, donc j'ai construit quelque chose d'intérêt pour la communauté python teeny / ferme. Mais il est basé sur les conclusions de ce fil. Où dois-je le dire?
code.AcreState.com/Recipes est un lieu standard. Je m'intéresse depuis que des décorateurs, des métaclasses (que je suppose que vous avez utilisé) et que l'héritage est un pita.
Oh, en fait @Richard, je ne savais pas où le mettre dans le site ici, mais je suppose que je viens d'étendre ma question initiale comme si je l'ai fait au-dessus de la section "Conclusion". (Un peu de lecture Google Wave serait pratique). Mais je suppose que je pourrais le mettre là-bas. C'est définitivement dans un état rudimentaire. En ce qui concerne les métaclasses, je ne les ai pas utilisées à Python. Je ne pense pas. Je suis peut-être sans le savoir? Obtenu un lien?
hehe ... vous sauriez si vous utilisiez des métaclasses :) (et non, vous n'êtes pas dans le code ci-dessus). Une recherche sur Google de "Métaclasses Python" est vraiment le meilleur point de départ. Quoi qu'il en soit, oui, ce décorateur ressemble à ce que vous voulez. Il y a quelques notes de code (vous pouvez utiliser getattr (obj, nom, par défaut i>) sans essayer / sauf, et que le décorateur accepte des arguments afin que vous n'ayez pas besoin de respecter le _After , _arning nommage, le
newfunc code> def pourrait simplement être inliné, pourrait utiliser Essayer / enfin pour le _after), mais sinon cela ressemble à ce que vous voulez.
La seule raison pour laquelle j'ai même mentionné des classes méta, c'est que vous pourriez configurer tous les éléments avant / après / après / autour de la «compilation», plutôt que de devoir la regarder au moment de l'exécution. En effet, le code utilisé pour la fabrication de classes méta est exécuté lorsque la classe est définie (similaire à la manière dont un décorateur est exécuté lorsque la fonction est définie). Dans les versions ultérieures de Python, il existe des décorateurs de niveau de classe, ce qui pourrait être plus facile que les classes méta. En tout état de cause, bon travail :)
@Richard merci! J'ai regardé les métaclasses. Les concepts que j'essayent de jeter à Python ici sonnent définitivement comme une question de métaclass maintenant! Créer un beau "clostype" métaclass me donnerait le concept de décorateur ci-dessus sans le décorateur non? Question: Je suis toujours limitée à la création d'une syntaxe personnalisée (droite?) Ce qui signifie que les noms de ces "méthodes partielles" auraient toujours besoin d'être là (voir originale DEFMETHODS en haut pour la syntaxe close). Les Python 2 ou 3 ont également quelque chose comme le paradigme que j'ai décrit? Diriez-vous que les décorateurs et les métaclasses peuvent donc être vraiment un bricolage?
Son bricolage, mais ce n'est pas un bricolage facile. Non, vous ne pouvez pas créer de syntaxe personnalisée, vous êtes toujours limité à l'utilisation de la syntaxe Python. Au lieu de _Before, vous pouvez attribuer un attribut à la fonction (
func.before = avant code>) étant enveloppé (les fonctions sont des objets comme tout, vous pouvez donc ajouter des attributs) ou utiliser une fermeture (comme ça dans la réponse acceptée).
D'accord. Donc, l'astuce là-bas pour ajouter des attributs aux fonctions est d'éviter toute écrasement des fonctions avec le même nom que celui utilisé à Clos avec les arguments: AVANT,: APRÈS,: autour de. Donc, si j'avais def MyMethod répété dans le code, le dernier def clouerait le premier, oui? Donc, ci-dessus, la création de noms différents pour les fonctions est nécessaire hein? Ce que je pouvais faire, c'est que la métaclasse recherche ces fonctions. Une chose que je n'aime pas à propos de la mienne est la voie est cassée en plusieurs parties ... Je vais essayer de faire d'autres modifications suggérées ci-dessus. J
@Richard. Je ne suis pas clair sur la façon de faire en sorte que Newfunc ...
Je ne sais pas ce que vous entendez par une fonction du même nom étant encombré. Si vous donnez une fonction le même nom que d'un autre dans la même classe, oui, il sera classé. Si vous voulez dire, vous nommez une fonction identique à celle d'une classe mère, il va masquer le parent (bien qu'il soit toujours accessible en utilisant Super ()))
Ouais. Parce que dans Lisp, ils ne sont pas classés: vous pouvez (Defmethod Helloworld () ()) et (Defmethod Helloworld: Avant () ())), etc. Ils sont les mêmes méthodes, mais les arguments et le protocole différencient les deux de les clobber. C'est pourquoi dans mon code, j'ai utilisé le "_ avant" concaténé à la fonction, de sorte qu'ils ne seraient pas encombrés.