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
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to