Defining magic methods in classes

I would like to define one object that can be repeated without creating a class and then an instance. Something like that:

class Thing(object):
    stuff = ["foo", "bar", "baz"]

    @classmethod
    def __iter__(cls):
        return iter(cls.stuff)

for thing in Thing:
    print thing

However, this does not actually work. Is there any way to do this?

+4
source share
2 answers

What Ashvini correctly stated in his comment is as follows. 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)
+3
source

Should it really Thingbe a type? You can make it an object that has type type behavior, which can be simpler:

class RealThing(object):
  pass

class ThingFactory(object):
  def __iter__(self):
    return iter(["foo", "bar", "baz"])

  def __call__(self):
    return RealThing()

Thing = ThingFactory()
0
source

All Articles