È possibile recuperare qualsiasi informazione di classe da un oggetto frame? So come ottenere il file (frame.f_code.co_filename), function (frame.f_code.co_name) e il numero di riga (frame.f_lineno), ma vorrei essere in grado di ottenere anche il nome della classe dell'oggetto attivo istanza del frame (o None se non in un'istanza).Python: come recuperare le informazioni sulla classe da un oggetto 'frame'?
risposta
Non credo che, a livello di oggetto frame, ci sia un modo per trovare l'oggetto della funzione Python che è stato chiamato.
Tuttavia, se il codice si basano sulla convenzione comune: denominazione del parametro di un metodo self
esempio, allora si potrebbe procedere come segue:
def get_class_from_frame(fr):
import inspect
args, _, _, value_dict = inspect.getargvalues(fr)
# we check the first parameter for the frame function is
# named 'self'
if len(args) and args[0] == 'self':
# in that case, 'self' will be referenced in value_dict
instance = value_dict.get('self', None)
if instance:
# return its class
return getattr(instance, '__class__', None)
# return None otherwise
return None
Se non si desidera utilizzare getargvalues
, è possibile utilizzare direttamente frame.f_locals
anziché value_dict
e frame.f_code.co_varnames[:frame.f_code.co_argcount]
anziché args
.
tenere presente che questo è ancora solo affidamento sulla convenzione, quindi non è portatile, e soggetto ad errori:
- se una funzione uso non metodo
self
come primo nome di parametro, quindiget_class_from_frame
indebitamente sarà restituisce la classe del primo parametro. - può essere fuorviante quando si lavora con descrittori (restituirà la classe del descrittore, non dell'istanza effettiva a cui si accede).
@classmethod
e@staticmethod
non avranno un parametroself
e sono implementati con descrittori.- e sicuramente molto più
A seconda di cosa esattamente si vuole fare, si potrebbe desiderare di prendere un po 'di tempo per scavare più a fondo e trovare soluzioni alternative per tutti questi problemi (si potrebbe verificare la funzione di telaio esistere nel restituisce classe e condivide la stessa fonte, è possibile rilevare le chiamate dei descrittori, lo stesso per i metodi di classe, ecc.)
Questo è un po 'più breve, ma fa lo stesso. Restituisce Nessuno se il nome della classe non è disponibile.
def get_class_name():
f = sys._getframe(1)
try:
class_name = f.f_locals['self'].__class__.__name__
except KeyError:
class_name = None
return class_name
Bella risposta! Ancora meglio, si potrebbe fare con '' f.f_locals ['__ class __'] .__ name__'', che dovrebbe coprire anche i casi '' @ classmethod'' e '' @ staticmethod''. –
@LucioPaiva che non funziona. Non esiste una chiave "__class __" in f_locals. – Pithikos
Mi sono imbattuto in questo post perché mi trovavo di fronte allo stesso problema. Non ho considerato il metodo 'self' una soluzione accettabile, tuttavia, per tutti i motivi già elencati.
Il codice seguente dimostra un approccio diverso: dato un oggetto frame, cerca le globali per un oggetto con nome membro e blocco di codice corrispondenti. La ricerca è difficilmente esaustiva quindi è possibile che non tutte le classi vengano scoperte, ma quali classi vengano trovate dovrebbero essere quelle che stiamo cercando perché verifichiamo i codici corrispondenti.
Oggetto del codice è quello di anteporre un nome di funzione con il suo nome di classe, se trovato:
def get_name(frame):
code = frame.f_code
name = code.co_name
for objname, obj in frame.f_globals.iteritems():
try:
assert obj.__dict__[name].func_code is code
except Exception:
pass
else: # obj is the class that defines our method
name = '%s.%s' % (objname, name)
break
return name
Nota l'uso di __dict__
invece di getattr
per evitare la cattura di classi derivate.
Nota inoltre che una ricerca globale può essere evitata se self = frame.f_locals['self']; obj = self.__class__
dà una corrispondenza, o qualsiasi obj in self.__class__.__bases__
o più profondo, quindi c'è sicuramente spazio per l'ottimizzazione/ibridazione.
Se un metodo è un metodo di classe, la classe sarà il primo argomento. Questo stampa il tipo del primo argomento se presente per ogni frame dello stack chiamante:
def some_method(self):
for f in inspect.getouterframes(inspect.currentframe()):
args, _,_, local_dict = inspect.getargvalues(f[0])
if args:
first_arg = args[0]
first_value = local_dict[first_arg]
print(type(first_value).__name__)
- 1. Come posso recuperare le informazioni del monitor?
- 2. come recuperare le informazioni dalla riga eliminata
- 3. recuperare un oggetto da hashset in C#
- 4. Come ordinare le informazioni sulla versione
- 5. Come recuperare le informazioni dell'intestazione HTTP da un metodo di servizio R # RESTful
- 6. Come recuperare Java informazioni vendor
- 7. Modo canonico in Python per aggiungere o recuperare le meta informazioni da/per docstring?
- 8. Come recuperare un singolo oggetto da Coredata usando un predicato
- 9. Git: recuperare un oggetto specifico da un telecomando
- 10. Python/Panda: trascinare le righe dal frame di dati sulla corrispondenza di stringhe dall'elenco
- 11. Python/Tkinter Come aggiornare le informazioni nella griglia
- 12. Come recuperare informazioni sui giornali da ISI Web of Knowledge?
- 13. Informazioni sulla variabile globale in Python
- 14. Tentativo di visualizzare le informazioni sulla versione del pacchetto in un messaggio "Informazioni"
- 15. Come recuperare e assegnare un oggetto NSDate da NSUserDefaults?
- 16. Come recuperare le informazioni della scheda grafica su Java?
- 17. Python: come "uccidere" un'istanza/oggetto di classe?
- 18. Come recuperare le informazioni EXIF di un'immagine in Rails
- 19. Come recuperare informazioni a livello di programmazione da LDAP
- 20. Elenca tutte le informazioni sulla sessione
- 21. Impossibile recuperare le informazioni utente tramite Facebook API o FQL
- 22. Come posso leggere le informazioni sulla firma digitale da un assembly .Net firmato?
- 23. disponibili informazioni sulla versione
- 24. Ottieni le informazioni sulla versione di un servizio installato?
- 25. Informazioni sulla callback app.listen()
- 26. Come recuperare le miniature quadrate da PHImageManager?
- 27. Informazioni sulla ricerca elastica
- 28. Informazioni sulla virtualizzazione
- 29. come ottenere le attuali informazioni sulla connessione wifi in Android
- 30. come salvare le informazioni sulla posizione in Firebase
Grazie per la risposta, Clément; è dettagliato e premuroso. Sto ancora sperando di ottenere più di una sola risposta! Ma se no, questo dovrà essere sufficiente ... –
OK, aspettato abbastanza a lungo. Questa è una buona risposta! Avevo sperato in un migliore supporto dalle strutture del telaio, ma è quello che è. Grazie ancora, Clément! –
Per aggiungerne uno alla lista, fai attenzione che 'self' possa essere un'istanza di una classe derivata, che potrebbe non essere quella a cui siamo interessati. – gertjan