2009-09-09 3 views
56

Как вы получаете список всех переменных в итеративном классе? Вроде как местные жители(), но для классаЗацикливание всех переменных-членов класса в python

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 
+0

Почему нельзя использовать использовать 'для поля в [self.bool143, self.bool2, self.blah, self.foo, self.foobar2000]'? Как получается, что вы не знаете переменные экземпляра класса? –

+4

S.Lott: Это то, что я в конечном итоге сделал. В моем реальном коде у меня есть 40 переменных, и я подумал, что было бы лучше, и больше DRY не нужно вручную составлять список итераций. – priestc

+3

Возможный дубликат [Итерация над объектными атрибутами в python] (https://stackoverflow.com/questions/11637293/iterate-over-object-attributes-in-python) –

ответ

90
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'] 
+5

почему экземпляр объекта: dir (Пример()) , а не только тип типа dir (Пример) – Erdal

+1

, потому что я предполагаю, что OP ищет переменные экземпляра (которые могут отсутствовать в классе). – truppo

+4

и как вы получаете значения? – knutole

5
>>> 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() - это то, что вы ищете.

0

Самый простой способ сделать это, чтобы сохранить все экземпляры класса в 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 
+0

Мне нравится идея (я мог бы использовать ее в текущем проекте). Это не ответ на вопрос: OP хочет перечислить атрибуты, а не сами экземпляры. – balpha

+0

@balpha: Ooops. Не прочитал вопрос. 90% времени, это дубликат «как найти все экземпляры класса». Фактический вопрос (теперь, когда вы указываете это), неразумен. Вы знаете переменные экземпляра, просто создайте список. –

23

@truppo: Ваш ответ почти правильно, но вызываемая всегда возвращает ложь, так как вы просто проездом в строке. Вам нужно что-то вроде следующего:

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

, которые будут отфильтровывать функции

70

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

vars(your_object) 
+3

Вам все равно нужно фильтровать __vars__, но это правильный ответ. – gaborous

+2

действительно нравится этот подход, и он будет использовать его, чтобы узнать, что сериализуется перед отправкой состояний по сети, например ... – Thom

+4

'vars' does * not * включает переменные класса, только переменные экземпляра. – DilithiumMatrix

-1
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