Pythonのクラスのすべてのメンバー変数をループする


91

反復可能なクラス内のすべての変数のリストを取得するにはどうすればよいですか?locals()のようなものですが、クラス用です

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)

これは戻るはずです

>>> e = Example()
>>> e.as_list()
bool143, bool2, foo

なぜ使用できないのfor field in [ self.bool143, self.bool2, self.blah, self.foo, self.foobar2000 ]ですか?クラスのインスタンス変数がわからないのはどうしてですか?
S.Lott 2009

4
S.Lott:それは私がとにかくやることになったものです。私の実際のコードでは、40個の変数があり、手動で反復リストを作成する必要がない方が、DRYの方が良いと思いました。
priestc 2009

回答:


151
dir(obj)

オブジェクトのすべての属性を提供します。メソッドなどからメンバーを自分で除外する必要があります。

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   

あなたに与えるでしょう:

['blah', 'bool143', 'bool2', 'foo', 'foobar2000']

9
オブジェクトをインスタンス化する理由:クラスタイプdir(Example)ではなくdir(Example())
Erdal 2011

8
どうやって値を取得しますか?
knutole 2013年

7
@knutole:getattr(object、attr)
opello 2014年

8
どのように機能しcallable(attr)ますか?attr文字列ではありませんか?
cubuspl42 2014

6
あなたが使用している必要がありますvars(Example).items()vars(instance.__class__).items()の代わりに、dir()あなたはその呼び出し可能かどうdirは唯一'を返しますので、確認したい場合はstring名前としてSを...
RRW

117

変数(関数なし)のみが必要な場合は、次を使用します。

vars(your_object)

5
まだ変数をフィルタリングする必要がありますが、これは正解です
2014

3
このアプローチが本当に好きです。たとえば、ネットワーク経由で状態を送信する前に、何をシリアル化するかを見つけるために使用します...
Thom

7
varsではないクラス変数、唯一のインスタンス変数が含まれます。
DilithiumMatrix 2016

2
@DilithiumMatrixクラス変数を取得するには、クラス自体でvars(THECLASSITSELF)を使用する必要があります。以下の私の答えを確認してください。
AmirHossein 2017

2
このメソッドを使用して、OPの質問に具体的に答えますmembers = list(vars(example).keys())。as(少なくともpython3では)varsdict、メンバー変数の名前をその値にマッピングして返します。
マイケルホール

28

@truppo:あなたの答えはほぼ正しいですが、文字列を渡すだけなので、callableは常にfalseを返します。次のようなものが必要です。

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

関数を除外します


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

—ご覧のとおり、これですべての属性が得られるため、少し除外する必要があります。しかし、基本的に、dir()あなたが探しているものです。


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

これを使って。


誤解を招く。デフォルトでは、クラスに属性「テーブル」はありません。
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

これを行う簡単な方法は、クラスのすべてのインスタンスをに保存することlistです。

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

オブジェクトが自然に発生することはありません。あなたのプログラムのいくつかの部分が理由でそれらを作成しました。作成は理由のために行われます。それらをリストに集めることも理由で行うことができます。

工場を使用する場合は、これを行うことができます。

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

私はそのアイデアが好きです(私は実際に現在のプロジェクトでそれを使用するかもしれません)。ただし、これは質問に対する答えではありません。OPは、インスタンス自体ではなく、属性を一覧表示したいと考えています。
balpha 2009

@balpha:おっと。質問を読んでいませんでした。90%の確率で、「クラスのすべてのインスタンスを見つける方法」の複製です。実際の質問(あなたがそれを指摘したので)は賢明ではありません。あなたはインスタンス変数を知っています、ただリストを作ってください。
S.Lott 2009
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.