在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

为什么不能使用use for field in [ self.bool143, self.bool2, self.blah, self.foo, self.foobar2000 ]?您不知道该类的实例变量如何发生?
S.Lott

4
S.Lott:那就是我最终要做的事情。在我的真实代码中,我喜欢40个变量,我认为不必手动创建迭代列表会更好,更DRY。
priestc

Answers:


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

8
以及如何获得这些价值?
knutole

7
@knutole:getattr(object,attr)
opello

8
callable(attr)工作如何?不是attr字符串吗?
cubuspl42 2014年

6
您应该使用vars(Example).items()vars(instance.__class__).items()代替,dir()如果您想检查其是否可调用,因为dir将仅返回strings作为名称
。。– rrw

117

如果只希望变量(不带函数),请使用:

vars(your_object)

5
您仍然需要过滤var,但这是正确的答案
令人惊讶的

3
真的很喜欢这种方法,例如在通过网络发送状态之前,它将使用它来找出要序列化的内容……
Thom 2015年

7
vars包括类变量,只有实例变量。
DilithiumMatrix

2
@DilithiumMatrix您需要在类本身上使用vars(THECLASSITSELF)来获取类变量。在下面检查我的答案。
阿米尔·侯赛因(AmirHossein)

2
使用此方法专门回答OP的问题:members = list(vars(example).keys())as(至少在python3中)vars返回dict成员变量名称与其值的映射。
迈克尔·霍尔

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 {}

用这个。


误导。默认情况下,类中没有属性“ table ”。
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

@balpha:糟糕!没有看问题。90%的时间是“如何查找类的所有实例”的重复。实际的问题(现在您已经指出了)是不明智的。您知道实例变量,只需列出一个即可。
S.Lott
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.