Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: Make class iterable

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 
like image 317
multipleinterfaces Avatar asked Mar 25 '11 15:03

multipleinterfaces


People also ask

How do you make a class iterable in Python?

To make a class as iterable, you have to implement the __iter__() and __next__() methods in that class. The __iter__() method allows us to make operations on the items or initializing the items and returns an iterator object.

Why is a class not iterable in Python?

If you are running your Python code and you see the error “TypeError: 'int' object is not iterable”, it means you are trying to loop through an integer or other data type that loops cannot work on. In Python, iterable data are lists, tuples, sets, dictionaries, and so on.

How do you make an object iterable?

To make the range object iterable (and thus let for..of work) we need to add a method to the object named Symbol. iterator (a special built-in symbol just for that). When for..of starts, it calls that method once (or errors if not found). The method must return an iterator – an object with the method next .

What does __ ITER __ do in Python?

The __iter__() function returns an iterator for the given object (array, set, tuple, etc. or custom objects). It creates an object that can be accessed one element at a time using __next__() function, which generally comes in handy when dealing with loops.


1 Answers

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 
like image 161
Sven Marnach Avatar answered Sep 17 '22 23:09

Sven Marnach