перебор всех переменных-членов класса в 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
4
С.Лотт: В любом случае я этим и закончил. В моем реальном коде у меня около 40 переменных, и я подумал, что было бы лучше и больше СУХОЙ, чтобы не создавать вручную список итераций.
priestc
3
Возможный дубликат итерации по атрибутам объекта в python
Тревор Бойд Смит,

Ответы:

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 08
6
вы должны были использовать vars(Example).items()или vars(instance.__class__).items()вместо, dir()если вы хотите проверить, вызывается ли он или нет, потому что dir будет возвращать только в stringкачестве имен ..
rrw
117

Если вы хотите использовать только переменные (без функций):

vars(your_object)
Нимо
источник
5
Вам по-прежнему нужно фильтровать вары, но это правильный ответ
gaborous
3
мне очень нравится этот подход, собираюсь использовать его, чтобы выяснить, что сериализовать, например, перед отправкой состояний по сети ...
Том
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("__")]

который отфильтрует функции

user235925
источник
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 {}

Использовать это.

user1825586
источник
Вводят в заблуждение. По умолчанию в классах нет атрибута 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