I came across code which makes the class Person
allow iteration here and here. It worked great for a single class, but I tried to modify it to allow iteration of multiple classes (separately) by changing _ClassRegistry
to a dict
, which would store
{class_str_name_1: [instance_obj_1, instance_obj_2, ...], ...}
instead of a list. My code is:
class ClassIter(type):
def __iter__(cls):
# iterate over the list in the dict value
return iter(cls._ClassRegistry[cls.__name__])
def __len__(cls):
return len(cls._ClassRegistry[cls.__name__])
class Person(metaclass=ClassIter):
_ClassRegistry = {}
def __init__(self, name, age):
if type(name).__name__ in self._ClassRegistry.keys():
self._ClassRegistry[type(self).__name__].append(self)
else:
self._ClassRegistry[type(self).__name__] = [self]
self.name, self.age = name, age
class Dog(metaclass=ClassIter):
_ClassRegistry = {}
def __init__(self, name, age, owned_by):
if type(name).__name__ in self._ClassRegistry.keys():
self._ClassRegistry[type(self).__name__].append(self)
else:
self._ClassRegistry[type(self).__name__] = [self]
self.name, self.age = name, age
self.owned_by = type(owned_by).__name__
Alice = Person("Alice", 20)
Bob = Person("Bob", 25)
Spud = Dog("Spud", 6, Alice)
Buster = Dog("Buster", 12, Bob)
for p in Person:
print(p.name, p.age)
for d in Dog:
print(d.name, d.age, d.owned_by)
Unfortunately this did not work, and the output is
Bob 25
Buster 12 Person
while I was hoping it would produce
Alice 20
Bob 25
Spud 6 Alice
Buster 12 Bob
so not only is it using the class name Person
instead of the name attribute (which is probably an easy fix but I've lost myself in the code) but also not storing the previous instances.
How can I either:
(1) convert this program to a class decorator (such as @iterator; class Person:
) to make it easier to implement this for multiple classes? or
(2) fix the program to work as expected using the current implementation?
Any help much appreciated, I am unexperienced in OOP.