I have inherited a project with many large classes constituent of nothing but class objects (integers, strings, etc). I’d like to be able to check if an attribute is present without needed to define a list of attributes manually.
Is it possible to make a python class iterable itself using the standard syntax? That is, I’d like to be able to iterate over all of a class’s attributes using for attr in Foo:
(or even if attr in Foo
) without needing to create an instance of the class first. I think I can do this by defining __iter__
, but so far I haven’t quite managed what I’m looking for.
I’ve achieved some of what I want by adding an __iter__
method like so:
class Foo: bar = "bar" baz = 1 @staticmethod def __iter__(): return iter([attr for attr in dir(Foo) if attr[:2] != "__"])
However, this does not quite accomplish what I’m looking for:
>>> for x in Foo: ... print(x) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'classobj' object is not iterable
Even so, this works:
>>> for x in Foo.__iter__(): ... print(x) bar baz
Advertisement
Answer
Add the __iter__
to the metaclass instead of the class itself (assuming Python 2.x):
class Foo(object): bar = "bar" baz = 1 class __metaclass__(type): def __iter__(self): for attr in dir(self): if not attr.startswith("__"): yield attr
For Python 3.x, use
class MetaFoo(type): def __iter__(self): for attr in dir(self): if not attr.startswith("__"): yield attr class Foo(metaclass=MetaFoo): bar = "bar" baz = 1