Können Klasseninformationen von einem Rahmenobjekt abgerufen werden? Ich weiß, wie man die Datei (frame.f_code.co_filename), die Funktion (frame.f_code.co_name) und die Zeilennummer (frame.f_lineno) bekommt, möchte aber auch den Namen der Klasse des aktiven Objekts erhalten können Instanz des Frames (oder Keine, falls nicht in einer Instanz).Python: Wie Klasseninformationen von einem 'Rahmen' Objekt abgerufen werden?
Antwort
Ich glaube nicht, dass es auf der Frame-Objekt-Ebene gibt es eine Möglichkeit, das tatsächliche Python-Funktionsobjekt zu finden, die aufgerufen wurde.
Allerdings, wenn Ihr Code über die gemeinsame Konvention verlassen: die Instanz Parameter einer Methode zu benennen self
, dann könnten Sie Folgendes tun:
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
Wenn Sie getargvalues
nicht verwenden, können Sie Verwenden Sie direkt frame.f_locals
statt value_dict
und frame.f_code.co_varnames[:frame.f_code.co_argcount]
anstelle von args
.
Beachten Sie, dass dies immer noch nur auf Konvention zu verlassen, so ist es nicht tragbar, und fehleranfällige:
- , wenn eine Nicht-Methode Funktion Verwendung
self
als Vorname Parameter, dannget_class_from_frame
wird falsch gib die Klasse des ersten Parameters zurück. - kann es bei der Arbeit mit Deskriptoren irreführend sein (es wird die Klasse des Deskriptors zurückgegeben, nicht die tatsächliche Instanz, auf die zugegriffen wird).
@classmethod
und@staticmethod
werden keineself
Parameter und sind mit Deskriptoren implementiert.- und sicherlich viel mehr
Je nachdem, was genau wollen Sie tun, könnten Sie einige Zeit in Anspruch nehmen wollen, tiefer zu graben und Abhilfen für all diese Fragen finden (Sie könnten die Rahmenfunktion existieren überprüfen in der zurückgegebene Klasse und teilen die gleiche Quelle, Erkennung von Descriptoraufrufen ist möglich, gleiche für Klassenmethoden, etc ..)
Dies ist ein bisschen kürzer, aber etwa gleich. Gibt None zurück, wenn der Klassenname nicht verfügbar ist.
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
Schöne Antwort! Noch besser, du könntest '' f.f_locals ['__ class __'] .__ name__'', was auch '' classmethod'' und '' staticmethod'' Fälle abdecken sollte. –
@LucioPaiva, die nicht funktioniert. In f_locals gibt es keinen Schlüssel "__class __". – Pithikos
Ich bin gerade auf diesen Beitrag gestoßen, da ich mit dem gleichen Problem konfrontiert war. Ich hielt die "Selbst" -Methode jedoch aus allen bereits genannten Gründen für keine akzeptable Lösung.
Der folgende Code demonstriert einen anderen Ansatz: Bei einem Rahmenobjekt durchsucht er die Globals nach einem Objekt mit übereinstimmendem Elementnamen und Codeblock. Die Suche ist nicht erschöpfend, daher ist es möglich, dass nicht alle Klassen aufgedeckt werden, aber welche Klassen gefunden werden, sollten diejenigen sein, nach denen wir suchen, weil wir übereinstimmende Codes verifizieren.
Objekt des Codes ist eine Funktion Namen mit seinen Klassennamen vorangestellt wird, wenn gefunden:
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
Beachten Sie die Verwendung von __dict__
statt getattr
zu verhindern abgeleiteten Klassen zu kontrollieren.
Hinweis weiter, dass eine globale Suche vermieden werden kann, wenn self = frame.f_locals['self']; obj = self.__class__
gibt eine Übereinstimmung, oder eine obj in self.__class__.__bases__
oder tiefer, so gibt es sicherlich Raum für die Optimierung/Hybridisierung.
Wenn eine Methode eine Klassenmethode ist, wird die Klasse das erste Argument sein. Dies gibt den Typ des ersten Arguments aus, wenn es für jeden aufrufenden Stapelrahmen vorhanden ist:
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. Klasseninformationen für Checkstyle
- 2. Wie kann verhindert werden, dass Windows Com-Klasseninformationen zwischenspeichert?
- 3. Rahmen Datetime-Objekt in einem json mit Python
- 4. Firebase-Werte werden ordnungsgemäß abgerufen, können aber nicht abgerufen werden?
- 5. Wie OracleCommand-Parameter von ProfiledDbCommand abgerufen werden
- 6. Drucken Klasseninformationen C# Formulare
- 7. Wie Informationen aus Curl mit Python-Subprozess abgerufen werden
- 8. Hibernate - wie ausgewählte Eigenschaften selektiv abgerufen werden?
- 9. Wie Werte aus einem DAO-Recordset dynamisch abgerufen werden?
- 10. Wie Core-Datenbeziehungen in einem einzigen NSFetchRequest abgerufen werden?
- 11. Wie Maven-Eigenschaften in einem JUnit-Test abgerufen werden?
- 12. Wie Dateiname und Lineno Attribut von SyntaxError abgerufen werden
- 13. JavaFX und TableView, wie Daten mit Hilfe einer LinkedList in einem Objekt abgerufen werden können
- 14. py2neo - Daten können nicht von einem Remote-Server abgerufen werden
- 15. Kann der Werttyp von einem beliebigen Iterator (C++) abgerufen werden?
- 16. Wert kann nicht von DatePicker abgerufen werden
- 17. wie ein Objekt mit As2 auf einem Rahmen zu entfernen #
- 18. Wie werden ID-Daten mit einem JQuery-Button abgerufen?
- 19. Abrufen von Callable-Objekt aus dem Rahmen
- 20. Wie Fehler beim Starten von sqlcmd aus C# abgerufen werden?
- 21. Prüfen, ob Objekt vom Garbage Collector abgerufen werden kann
- 22. Daten konnten nicht als JSON-Objekt abgerufen werden
- 23. Kann die Zeichenfolge "interval_spec" vom DateInterval-Objekt abgerufen werden?
- 24. Wie kann ein Wert von mithilfe von jQuery abgerufen werden?
- 25. Hinzufügen von Rahmen zu einem Bild mit Python
- 26. Gesamtindex von Listview kann nicht abgerufen werden
- 27. Wie Artikel aus dbpedia abgerufen werden?
- 28. Wie werden nur neue Daten abgerufen?
- 29. Wie Bilder in einer Suchmaschine abgerufen werden?
- 30. Wie CheckBox SelectedValue in Jquery abgerufen werden
Vielen Dank für Ihre Antwort, Clément; es ist detailliert und durchdacht. Ich hoffe immer noch auf mehr als nur eine Antwort! Aber wenn nicht, muss dieser hier genügen ... –
OK, warte lange genug. Das ist eine gute Antwort! Ich hatte auf bessere Unterstützung von den Rahmenstrukturen gehofft, aber es ist was es ist. Nochmals vielen Dank, Clément! –
Um eins zur Liste hinzuzufügen, seien Sie vorsichtig, dass "self" eine Instanz einer abgeleiteten Klasse sein könnte, die möglicherweise nicht die ist, an der wir interessiert sind. – gertjan