Ich möchte die Attribute einer Klasse erhalten, sagen wir:
class MyClass():
a = "12"
b = "34"
def myfunc(self):
return self.a
using MyClass.__dict__
gibt mir eine Liste von Attributen und Funktionen und sogar Funktionen wie __module__
und __doc__
. Während MyClass().__dict__
gibt mir ein leeres Diktat, es sei denn, ich habe explizit einen Attributwert dieser Instanz festgelegt.
Ich möchte nur die Attribute, im obigen Beispiel wären dies: a
undb
python
python-2.7
class
attributes
Mohamed Khamis
quelle
quelle
Antworten:
Probieren Sie das Inspektionsmodul aus .
getmembers
und die verschiedenen Tests sollten hilfreich sein.BEARBEITEN:
Beispielsweise,
Jetzt gehen mir die speziellen Methoden und Attribute auf die Nerven - diese können auf verschiedene Arten behandelt werden, von denen die einfachste darin besteht, nur nach Namen zu filtern.
... und die kompliziertere davon kann spezielle Attributnamenprüfungen oder sogar Metaklassen beinhalten;)
quelle
attributes = inspect.getmembers(MyClass, lambda a:not(inspect.isroutine(a)))
print [a[0] for a in attributes if '_' not in a[0]]
like_this
! Außerdem werden "private" Attribute vermieden, die Sie möglicherweise absichtlich erstellt haben.inspect.getmembers(MyClass, ...
,MyClass
kann durch eine Klasse oder ein Objekt ersetzt werden, und wenn Sie die Liste der Werte der Objekte benötigen, müssen Sie ersetzen ,MyClass
indem Sie Ihre Objektvariable (oder ,self
wenn Sie setzen dieser Ausdruck in einerdef __repr__()
Methode wie ich).i = inspect.getmembers(MyClass, lambda a:not(inspect.isroutine(a))); z = [_[1] for _ in i if _[0] in '__dict__'][0]
und dann geht es nur noch darum, die Schlüssel von z zu erhalten.quelle
if not i.startswith('_')
stattif i[:1] != '_'
?.__dict__.keys()
werden keine Attribute von der übergeordneten Klasse eingeschlossen .myfunc
ist ein Attribut vonMyClass
. So wird es gefunden, wenn Sie laufen:Es sucht nach einem Attribut auf
myinstance
namedmyfunc
, findet keines, sieht, dassmyinstance
es sich um eine Instanz handelt,MyClass
und sucht dort nach.Die vollständige Liste der Attribute für
MyClass
lautet also:(Beachten Sie, dass ich dir nur als schnelle und einfache Möglichkeit verwende, die Mitglieder der Klasse aufzulisten: Es sollte nur explorativ verwendet werden, nicht im Produktionscode.)
Wenn Sie nur bestimmte Attribute möchten, müssen Sie diese Liste mit einigen Kriterien filtern, weil
__doc__
,__module__
undmyfunc
nicht in irgendeiner Weise etwas Besonderes sind, sie sind Attribute in genau der gleichen Weise,a
undb
sind.Ich habe das Inspektionsmodul, auf das sich Matt und Borealid beziehen, noch nie verwendet, aber aus einem kurzen Link geht hervor, dass es Tests gibt, die Ihnen dabei helfen, aber Sie müssen Ihre eigene Prädikatfunktion schreiben, da es so aussieht, als ob Sie es möchten ist ungefähr das Attribut, das den
isroutine
Test nicht besteht und nicht mit zwei Unterstrichen beginnt und endet.Beachten Sie auch:
class MyClass():
Wenn Sie in Python 2.7 verwenden, verwenden Sie die veralteten Klassen im alten Stil. Sofern Sie dies nicht absichtlich tun, um die Kompatibilität mit extrem alten Bibliotheken zu gewährleisten, sollten Sie stattdessen Ihre Klasse als definierenclass MyClass(object):
. In Python 3 gibt es keine "alten" Klassen, und dieses Verhalten ist die Standardeinstellung. Wenn Sie jedoch Newstyle-Klassen verwenden, erhalten Sie viel mehr automatisch definierte Attribute:quelle
dir()
: " Da dir () in erster Linie als Annehmlichkeit für die Verwendung an einer interaktiven Eingabeaufforderung bereitgestellt wird, versucht es, einen interessanten Satz von Namen mehr als einen streng oder konsistent definierten Satz von Namen und dessen Details bereitzustellen Das Verhalten kann sich zwischen den Releases ändern . "(siehe Dokumentation vondir()
).Es ist einfach, nur die Instanzattribute abzurufen.
Es ist jedoch etwas schwieriger , auch die Klassenattribute ohne die Funktionen zu erhalten.
Nur Instanzattribute
Wenn Sie nur Instanzattribute auflisten müssen, verwenden Sie einfach
for attribute, value in my_instance
.__dict__
.items()
Instanz- und Klassenattribute
Um auch die Klassenattribute ohne die Funktionen zu erhalten, ist der Trick zu verwenden
callable()
.Aber statische Methoden sind nicht immer
callable
!Daher anstelle von
callable(value)
usecallable
(getattr
(MyClass, attribute))
Beispiel
Hinweis:
print_class_attributes()
sollte aber nicht in diesem blöden und einfachen Beispiel sein.@staticmethod
Resultat für python2
Gleiches Ergebnis für python3
quelle
MyClass().__class__.__dict__
Das "Recht" war jedoch, dies über das Inspektionsmodul zu tun .
quelle
MyClass().__class__.__dict__
==MyClass.__dict__
MyClass().__class__.__dict__ != MyClass().__dict__
, aber Yak enthält nicht die Klammern auf der rechten Seite, in deren Fall er / sie korrekt istFür eine Instanz von MyClass, z
Verwendung
type(mc)
anstelle vonMyClass
in der Liste Verständnis. Wenn man jedoch dynamisch ein Attribut hinzufügtmc
, z. B.mc.c = "42"
, wird das Attribut bei Verwendungtype(mc)
in dieser Strategie nicht angezeigt. Es werden nur die Attribute der ursprünglichen Klasse angegeben.Um das vollständige Wörterbuch für eine Klasseninstanz zu erhalten, müssten Sie die Wörterbücher von
type(mc).__dict__
und KOMBINIERENmc.__dict__
.quelle
Ich weiß nicht, ob bis jetzt etwas Ähnliches gemacht wurde oder nicht, aber ich habe eine nette Attributsuchfunktion mit vars () gemacht. vars () erstellt ein Wörterbuch mit den Attributen einer Klasse, die Sie durchlaufen.
Ich entwickle ein ziemlich umfangreiches Textabenteuer in Python. Meine Player-Klasse hat bisher über 100 Attribute. Ich benutze dies, um nach bestimmten Attributen zu suchen, die ich sehen muss.
quelle
Dies kann ohne Inspektion geschehen, denke ich.
Nehmen Sie an der folgenden Klasse teil:
Betrachten Sie die Mitglieder zusammen mit ihren Typen:
... gibt:
Um nur die Variablen auszugeben, müssen Sie nur die Ergebnisse nach Typ und Namen filtern, die nicht mit '__' beginnen. Z.B
Das ist es.
Hinweis: Wenn Sie Python 3 verwenden, konvertieren Sie die Iteratoren in Listen.
Wenn Sie eine robustere Methode wünschen, verwenden Sie inspect .
quelle
Python 2 & 3, ohne Importe, filtern Objekte nach ihrer Adresse
Kurz gesagt: Lösungen:
Rückgabe dict {Attributname: Attributwert} , gefilterte Objekte. dh
{'a': 1, 'b': (2, 2), 'c': [3, 3]}
Rückgabeliste [Attributnamen] , gefilterte Objekte. dh
['a', 'b', 'c', 'd']
Rückgabeliste [attribute_values] , gefilterte Objekte. dh
[1, (2, 2), [3, 3], {4: 4}]
Objekte nicht filtern
if
Zustand entfernen . Rückkehr{'a': 1, 'c': [3, 3], 'b': (2, 2), 'e': <function <lambda> at 0x7fc8a870fd70>, 'd': {4: 4}, 'f': <object object at 0x7fc8abe130e0>}
Lösung in langer Zeit
Solange die Standardimplementierung von
__repr__
nicht überschrieben wird, wird dieif
Anweisung zurückgegeben,True
wenn sich die hexadezimale Darstellung der Position im Speicher vonval
in der__repr__
Rückgabezeichenfolge befindet.In Bezug auf die Standardimplementierung von
__repr__
könnten Sie diese Antwort nützlich finden . Zusamenfassend:Wich gibt einen String zurück wie:
Der Speicherort jedes Elements wird über die
id()
Methode ermittelt.Python Docs sagt über id ():
Versuchen Sie es selbst
Ausgabe:
Hinweis :
Getestet mit Python
2.7.13
und Python3.5.3
In Python wird 2.x gegenüber
.iteritems()
bevorzugt.items()
quelle
Ich musste kürzlich etwas Ähnliches wie diese Frage herausfinden, deshalb wollte ich einige Hintergrundinformationen veröffentlichen, die für andere hilfreich sein könnten, die in Zukunft mit denselben Fragen konfrontiert sind.
So funktioniert es in Python (von https://docs.python.org/3.5/reference/datamodel.html#the-standard-type-hierarchy ):
MyClass
ist ein Klassenobjekt,MyClass()
ist eine Instanz des Klassenobjekts. Eine Instanz enthält__dict__
nur Attribute und Methoden, die für diese Instanz spezifisch sind (zself.somethings
. B. ). Wenn ein Attribut oder eine Methode Teil einer Klasse ist, befindet sie sich in der Klasse__dict__
. Wenn Sie dies tunMyClass().__dict__
, wird eine Instanz vonMyClass
ohne Attribute oder Methoden außer den Klassenattributen erstellt, also leer__dict__
Wenn Sie also sagen
print(MyClass().b)
, prüft Python zuerst das Diktat der neuen InstanzMyClass().__dict__['b']
und findet es nichtb
. Es überprüft dann die KlasseMyClass.__dict__['b']
und findetb
.Deshalb benötigen Sie das
inspect
Modul, um denselben Suchvorgang zu emulieren.quelle
Sie können
dir()
in einem Listenverständnis die Attributnamen abrufen:Verwenden Sie
getattr()
diese Option , um die Attribute selbst abzurufen:quelle
Meine Lösung, um alle Attribute (keine Methoden) einer Klasse abzurufen (wenn die Klasse über eine ordnungsgemäß geschriebene Dokumentzeichenfolge verfügt, in der die Attribute klar geschrieben sind):
Dieses Stück
cls.__dict__['__doc__']
extrahiert den Docstring der Klasse.quelle
Warum müssen Sie die Attribute auflisten? Scheint, dass Ihre Klasse semantisch eine Sammlung ist. In diesen Fällen empfehle ich die Verwendung von enum:
Listen Sie Ihre Attribute auf? Nichts einfacher als das:
quelle
Wenn Sie ein Attribut "erhalten" möchten, gibt es eine sehr einfache Antwort , die offensichtlich sein sollte: getattr
Es funktioniert sowohl in Python 2.7 als auch in Python 3.x.
Wenn Sie eine Liste dieser Elemente wünschen, müssen Sie weiterhin inspect verwenden.
quelle
zwei Funktionen:
verwenden:
quelle
Folgendes möchte ich.
Testdaten
quelle
Ich weiß, dass dies vor drei Jahren war, aber für diejenigen, die in Zukunft mit dieser Frage kommen werden, für mich:
funktioniert gut.
quelle
attribute
vorher ist.Sie können verwenden
MyClass.__attrs__
. Es gibt nur alle Attribute dieser Klasse. Nichts mehr.quelle