Come di 2.4 (2.6 per classi), python permette di decorare una funzione con un'altra funzione:__decorated__ per decoratori Python
def d(func): return func
@d
def test(first): pass
E 'una vantaggiosa zucchero sintattico. Puoi fare ogni genere di cose belle con i decoratori senza fare casino. Tuttavia, se vuoi scoprire la funzione originale che hai decorato devi saltare attraverso i cerchi (come Cls.method.__func__.__closure__[0].cell_contents
o peggio).
ho trovato me stesso che desiderano per un modo migliore e ha scoperto che vi era stata qualche discussione su python-dev su come aggiungere una variabile denominata __decorated__
alla [nuova] la funzione restituito dal decoratore. Tuttavia, sembra che non sia andato da nessuna parte.
Essendo una persona avventurosa, e avendo avuto un'esperienza pitone piuttosto pesante per circa 4 anni, ho pensato di esaminare l'implementazione di __decorated__
nell'origine del compilatore Python, solo per vedere come va.
A dire il vero non ho mai approfondito la C sotto il cofano, quindi le mie prime ore hanno cercato solo di dare un senso a come funziona il codice C sottostante. Quindi, in primo luogo, quali sarebbero le migliori risorse per capire cosa dovrei cambiare/aggiungere per __decorator__
?
In secondo luogo, se un decoratore restituisce una nuova funzione, __decorated__
restituisce solo la funzione originale decorata. Tuttavia, se il decoratore restituisce la funzione originale, che cosa dovrebbe accadere? Qui ci sono tre opzioni mi veniva in mente (il terzo è il mio preferito):
- non aggiungere
__decorator__
. - Aggiungi
__decorator__
ma impostarlo su Nessuno. - Aggiungi
__decorator__
e impostalo comunque sulla funzione originale.
Quindi, se dovesse succedere, quale pensi che sarebbe l'opzione migliore?
UPDATE:
Qualcun altro brought to my attention uno scenario che avevo perso. Cosa succede quando il decoratore non restituisce né la funzione originale né una funzione che avvolge l'originale? A quel punto, nulla mantiene un riferimento alla funzione originale e otterrà i dati raccolti. (Grazie Oddthinking!)
Quindi in tal caso, penso che vorrei ancora andare con la terza opzione. L'oggetto restituito dal decoratore otterrebbe un nome __decorated__
che fa riferimento alla funzione originale. Ciò significherebbe che non sarebbe raccolta di rifiuti.
Mi sembra strano che la funzione di una definizione di classe scompaia completamente perché l'hai decorata. Nella mia mente questo è ancora più motivo per avere un attributo __decorated__
applicato per ogni decoratore. Tuttavia, è più probabile che la mia intuizione sia errata e che il comportamento attuale sia quello che la maggior parte delle persone si aspetterebbe. Qualche idea?
p.s. questa è un'estensione di un precedente, più generale question che avevo. Sono andato anche per maggiori informazioni sulla prima parte con un post separate.
quindi stai pensando al prossimo passaggio, cioè, come si noterà la funzione decorata che è decorata? http://stackoverflow.com/questions/3109289/how-can-python-function-access-its-own-attributes :) – mykhal
Come funziona con '@ property'? Come in, i decoratori non devono restituire funzioni. – habnabit
@Aaron, suppongo che aggiungerai "__decorated__" a qualsiasi cosa venga restituita, funzione o meno. –