4

I would like to define a single object that can be iterated over without having to create a class and then an instance. Something like this:

class Thing(object): stuff = ["foo", "bar", "baz"] @classmethod def __iter__(cls): return iter(cls.stuff) for thing in Thing: print thing 

However this doesn't actually work. Is there any way to do this?

3
  • 4
    For a class define __iter__ on the metaclass. Commented Apr 20, 2015 at 22:06
  • Magic method lookup occurs on the class. So you'll either have to create an instance and class or class and metaclass. But it also seems like you could just subclass list (at least in your example). Commented Apr 20, 2015 at 22:12
  • @jedwards Ok, I was trying to avoid creating extra things in the namespace of my module but I guess I'll just have to deal with it. This is a much simplified example, in my actual use case there's more internal state than just a list. Commented Apr 20, 2015 at 22:16

2 Answers 2

3

What Ashwini correctly suggested in his comment is the following. This works in Python 2.

class ThingType(type): __stuff__ = ["foo", "bar", "baz"] @classmethod def __iter__(cls): return iter(cls.__stuff__) class Thing(object): __metaclass__ = ThingType for thing in Thing: print thing 

And this works in Python 3:

class ThingType(type): __stuff__ = ["foo", "bar", "baz"] @classmethod def __iter__(cls): return iter(cls.__stuff__) class Thing(object, metaclass=ThingType): pass for thing in Thing: print(thing) 
Sign up to request clarification or add additional context in comments.

2 Comments

My bad, missed the location of stuff. :/
It will work because(even without classmethod) Python can find the attribute by looking up in the MRO. Earlier I misread it and thought you had defined stuff in Thing not ThingType. So... ;-)
0

Does Thing actually need to be a type? You could make it an object that has type-like callable behavior, which would probably be simpler:

class RealThing(object): pass class ThingFactory(object): def __iter__(self): return iter(["foo", "bar", "baz"]) def __call__(self): return RealThing() Thing = ThingFactory() 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.