David
David

Reputation: 523

Define methods for multiple classes

I'm working on a small personal project where I created many classes. Each class has its own register containing all its instances:

class IterReg(type):
    # Register of all objects for iteration
    def __iter__(cls):
        return iter(cls._reg.values())

The "template" which I use for each class is

class Point(object):
    # Point object
    __metaclass__ = IterReg
    _reg = dict()
    counter = 0

    # Initialize
    def __init__(self, name):
        self.name = name
        self._reg[self.name] = self
        Point.counter += 1

    # Return register keys
    @staticmethod
    def get_reg_keys(cls):
        return cls._reg.keys()

And some other (not important for a MWE) stuff. If I initialize, e.g., a = Point("Point A"), I can then call:

>>> a.get_reg_keys()
['Point A']

which is (obviously) the same result that I get from

Point.get_reg_keys()

Now my question: is there a way to define this method once for all classes (i.e. somehow in the metaclass). I first thought something like this had worked:

class IterReg(type):
    # Register of all objects for iteration
    def __iter__(cls):
        return iter(cls._reg.values())

    def get_reg_keys(cls):
        return cls._reg.keys()

But then I can just call get_reg_keys() from the class (i.e. Point.get_reg_keys()) and not from any instance of it.

Upvotes: 2

Views: 4872

Answers (1)

James
James

Reputation: 36598

You can define a generic class that has .get_reg_keys() and subclass it when you want to use that method. In the below example, any class that inherits from Generic will have the .get_reg_keys() method.

class IterReg(type):
    # Register of all objects for iteration
    def __iter__(cls):
        return iter(cls._reg.values())

class Generic(object):
    @classmethod
    def get_reg_keys(cls):
        return cls._reg.keys()

class Point(Generic):
    # Point object
    __metaclass__ = IterReg
    _reg = dict()
    counter = 0

    # Initialize
    def __init__(self, name):
        self.name = name
        self._reg[self.name] = self
        Point.counter += 1


a = Point('Point A')
a.get_reg_keys()
# returns:
['Point A']

Upvotes: 2

Related Questions