Durchlaufen aller Mitgliedsvariablen einer Klasse in Python

88

Wie erhält man eine Liste aller Variablen in einer Klasse, die iterierbar ist? Ein bisschen wie Einheimische (), aber für eine Klasse

class Example(object):
    bool143 = True
    bool2 = True
    blah = False
    foo = True
    foobar2000 = False

    def as_list(self)
       ret = []
       for field in XXX:
           if getattr(self, field):
               ret.append(field)
       return ",".join(ret)

dies sollte zurückkehren

>>> e = Example()
>>> e.as_list()
bool143, bool2, foo
Priester
quelle
Warum kann nicht verwendet werden for field in [ self.bool143, self.bool2, self.blah, self.foo, self.foobar2000 ]? Wie kommt es, dass Sie die Instanzvariablen der Klasse nicht kennen?
S.Lott
4
S.Lott: Das habe ich sowieso getan. In meinem realen Code habe ich ungefähr 40 Variablen, und ich dachte, es wäre besser und trockener, die Iterationsliste nicht manuell erstellen zu müssen.
Priester
3
Mögliches Duplikat von Iterieren über Objektattribute in Python
Trevor Boyd Smith

Antworten:

148
dir(obj)

gibt Ihnen alle Attribute des Objekts. Sie müssen die Mitglieder selbst aus Methoden usw. herausfiltern:

class Example(object):
    bool143 = True
    bool2 = True
    blah = False
    foo = True
    foobar2000 = False

example = Example()
members = [attr for attr in dir(example) if not callable(getattr(example, attr)) and not attr.startswith("__")]
print members   

Werde dir geben:

['blah', 'bool143', 'bool2', 'foo', 'foobar2000']
Truppo
quelle
8
Warum ein Objekt instanziieren: dir (Beispiel ()) statt nur des Klassentyps dir (Beispiel)
Erdal
8
und wie bekommt man die werte
Knutole
7
@knutole: getattr (Objekt, attr)
opello
8
Wie funktioniert das callable(attr)? Ist das kein attrString?
cubuspl42
6
Sie sollten verwendet haben vars(Example).items()oder vars(instance.__class__).items()stattdessen, dir()ob Sie überprüfen möchten, ob es aufrufbar ist oder nicht, da dir nur stringals Namen
zurückgibt
114

Wenn Sie nur die Variablen (ohne Funktionen) möchten, verwenden Sie:

vars(your_object)
Nimo
quelle
5
Sie müssen noch vars filtern, aber dies ist die richtige Antwort
gaborous
2
Ich mag diesen Ansatz wirklich, um herauszufinden, was zu serialisieren ist, bevor zum Beispiel Zustände über das Netzwerk gesendet werden ...
Thom
7
varsenthält nicht die Klassenvariablen, sondern nur die Instanzvariablen.
DilithiumMatrix
1
@DilithiumMatrix Sie müssen vars (THECLASSITSELF) für die Klasse selbst verwenden, um Klassenvariablen abzurufen. Überprüfen Sie meine Antwort unten.
AmirHossein
1
Verwenden Sie diese Methode, um die Frage des OP spezifisch zu beantworten: members = list(vars(example).keys())as (zumindest in python3) varsgibt eine dictZuordnung des Namens der Mitgliedsvariablen zu ihrem Wert zurück.
Michael Hall
27

@truppo: Ihre Antwort ist fast korrekt, aber callable gibt immer false zurück, da Sie nur eine Zeichenfolge übergeben. Sie benötigen etwa Folgendes:

[attr for attr in dir(obj()) if not callable(getattr(obj(),attr)) and not attr.startswith("__")]

das wird Funktionen herausfiltern

user235925
quelle
6
>>> a = Example()
>>> dir(a)
['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__',
'__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__',
'__sizeof__', '__str__', '__subclasshook__', 'bool143', 'bool2', 'blah',
'foo', 'foobar2000', 'as_list']

- Wie Sie sehen, erhalten Sie alle Attribute, sodass Sie ein wenig herausfiltern müssen. Aber im Grunde dir()ist es das , wonach Sie suchen.

balpha
quelle
-1
row2dict = lambda r: {c.name: str(getattr(r, c.name)) for c in r.__table__.columns} if r else {}

Benutze das.

user1825586
quelle
Irreführend. Standardmäßig gibt es in Klassen kein Attribut ' Tabelle '.
ben26941
-2
    class Employee:
    '''
    This class creates class employee with three attributes 
    and one function or method
    '''

    def __init__(self, first, last, salary):
        self.first = first
        self.last = last
        self.salary = salary

    def fullname(self):
        fullname=self.first + ' ' + self.last
        return fullname

emp1 = Employee('Abhijeet', 'Pandey', 20000)
emp2 = Employee('John', 'Smith', 50000)

print('To get attributes of an instance', set(dir(emp1))-set(dir(Employee))) # you can now loop over
Abhijeet Pandey
quelle
-3

Der einfache Weg, dies zu tun, besteht darin, alle Instanzen der Klasse in a zu speichern list.

a = Example()
b = Example()
all_examples = [ a, b ]

Objekte entstehen nicht spontan. Ein Teil Ihres Programms hat sie aus einem bestimmten Grund erstellt. Die Erstellung erfolgt aus einem bestimmten Grund. Das Sammeln in einer Liste kann auch aus einem bestimmten Grund erfolgen.

Wenn Sie eine Fabrik verwenden, können Sie dies tun.

class ExampleFactory( object ):
    def __init__( self ):
        self.all_examples= []
    def __call__( self, *args, **kw ):
        e = Example( *args, **kw )
        self.all_examples.append( e )
        return e
    def all( self ):
        return all_examples

makeExample= ExampleFactory()
a = makeExample()
b = makeExample()
for i in makeExample.all():
    print i
S.Lott
quelle
Ich mag die Idee (ich könnte sie tatsächlich in einem aktuellen Projekt verwenden). Es ist jedoch keine Antwort auf die Frage: Das OP möchte die Attribute auflisten, nicht die Instanzen selbst.
Balpha
@balpha: Ups. Ich habe die Frage nicht gelesen. In 90% der Fälle handelt es sich um ein Duplikat von "Wie finde ich alle Instanzen einer Klasse?". Die eigentliche Frage (jetzt, wo Sie darauf hinweisen) ist nicht sinnvoll. Sie kennen die Instanzvariablen, erstellen Sie einfach eine Liste.
S.Lott