перебор всех переменных-членов класса в 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

Ответы:


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("__")]

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


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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.