Iterating over objects of a class

Kottiyath n.kottiyath at gmail.com
Wed Dec 24 19:15:29 CET 2008


On Dec 24, 10:52 pm, "Diez B. Roggisch" <de... at nospam.web.de> wrote:
> Kottiyath schrieb:
>
> > Hi,
> >    How can I iterate over all the objects of a class?
> >    I wrote the code like following:
> > class baseClass(object):
>
> Consider adopting PEP 8  coding conventions.
>
>
>
> >     __registry = []
>
> >     def __init__(self, name):
> >         self.__registry.append(self)
> >         self.name = name
>
> >     def __iter__(self):
> >         baseClass.item = 0
> >         return self.__registry[0]
>
> >     def next(self):
> >         if baseClass.item >= len(self.__registry):
> >             raise StopIteration
> >         baseClass.item += 1
> >         return self.__registry[baseClass.item - 1]
>
> > For testing, create the following objects-
> > a = baseClass("Test1")
> > b = baseClass("Test2")
>
> > class subClass (baseClass):
> >    pass
> > c = subClass("Test3")
>
> > ---->Actual Iteration<----
> > for i in a:
> >     print i.name
>
> > Test1
> > Test2
> > Test3
>
> > ---------------------------------------------------
> > I see the following problems in the code:
> > 1. I have to iterate over any of the objects. For correctness, I
> > wanted to iterate over the class, like
> > for i in baseClass():
> >    do x
> > but that will will create one more object - which I do not want.
>
> > 2. If the subclass wants to do somethings in its constructor, I am not
> > sure how to update the registry.
> > class subClass (baseClass):
> >    def __init__(self, name):
> >        **do something**
> >        super.init(self, name)  ----> This errors out, saying it needs
> > super, not subClass
>
> You don't show the actual traceback, however the idiom for invoking
> super for new-style-classes is
>
> super(subClass, self).__init__(name)
>
> for your case.
>
> > Another method I thought of implementing it was using generators -
> > where-in baseClass.objects() is a generator which will yield the
> > objects one by one - but even then the second issue remains.
> > If somebody can help me out, I would be very thankful.
>
> Using a generator or not isn't the issue here.
>
> What you need is a *class*-based access, not instance-based. There are
> various methods to accomplish this. The simplest is to ditch the
> obnoxious __registry as name, and just do
>
> class BaseClass(object):
>
>     REGISTRY = []
>
> Then iterating is a simple matter of
>
> for instance in BaseClass.REGISTRY:
>     ...
>
> Case solved. Alternatively, if you insist on the concept of privacy for
> that registry, you can use a classmethod:
>
> class BaseClass(object):
>
>     @classmethod
>     def registry(cls):
>         for i in cls.__registry:
>             yield i
>
> Last but not least you *could* go for a __metaclass__ with an
> __getitem__-method, that makes thinks look fancy because you then can do:
>
> for instance in BaseClass:
>      ...
>
> I leave it as an exercise to you - gotta go christmas dining now :)
>
> Diez

Thank you Very much, Diez. I was able to do the Generator and the
super part of it, but I never even thought of the metaclass option.
I will try it out. Thank you very much.
Merry Christmas.
P.S - >Also, I will use the PEP 8 coding conventions



More information about the Python-list mailing list