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

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

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']

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)

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


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.


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

Benutze das.


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

-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

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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.