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
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.
Regards
K
Consider adopting PEP 8 coding conventions.
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
Is there any other way out in this case?
I have factory methods - and I have to loop over them - sort of Chain
of Responsibility pattern.
Having a registry inside the class instance and looping through them
was the only clean thing I could think of.
I understand that garbage collection would be an issue - but is there
any way out?
>> The other thing to remember is that because the 'registry' contains
>> references to the instances, they won't be garbage collected.
>
> Is there any other way out in this case?
> I have factory methods - and I have to loop over them - sort of Chain
> of Responsibility pattern.
> Having a registry inside the class instance and looping through them
> was the only clean thing I could think of.
> I understand that garbage collection would be an issue - but is there
> any way out?
You may keep all that structures - just use weak references (see the
weakref module).
There isn't a WeakList nor WeakSet out-of-the-box but you may use a
WeakKeyDictionary (set the value to anything, None by example).
--
Gabriel Genellina
Thank you very much, Gabriel.
I am very thankful to everyone.
Search for weakref in the documentatione.
In this case, I'd use a WeakValueDictionary() from id(obj) to obj.
Note id(obj) is guaranteed to be unique for all objects in existance,
but the id of a collected object may match the id of a new object.
>>> import weakref
>>> d = weakref.WeakValueDictionary()
>>> vs = [Int(n) for n in range(3, 500, 70)]
>>> for n in vs:
d[id(n)] = n
v = Int(n+1)
d[id(v)] = v
>>> for obj in d.values(): # values is safer than itervalues
print obj
>>> # note the above was the following, which fails:
>>> for v in d.values(): # values is safer than itervalues
print v
For extra credit, explain why values is better.
--Scott David Daniels
Scott....@Acm.Org