Ken T
Ken T

Reputation: 2553

Implement logic between different instances of the same class

I want to implement some logic between different instances of the same class but I don't how to properly do it. Both review and advice are required.

It is best to start with an example. Supposed I have a class foo. There are three attributes in this class - id, group and nitem.

The logic to be implemented is that the instance of foo if under the same group should have the same number of items (i.e. nitem).

Some may have noticed that I have already implemented a piece of logic between instances which is counting the number of instances via foo._id. But you can also understand easily how naive this method is. If you create three instances of foo and delete the middle instance. The last instance will still have an id=3.

class foo(object):
    _id = 0
    def __init__(self, group, nitem):
        foo._id += 1
        self.id = foo._id
        self.group = group
        self.nitem = nitem

if __name__ == "__main__":
    a = foo(1, 100)
    b = foo(2, 10) #no error. Different groups can have different nitem.
    c = foo(1, 10) # I want this to raise error.Same groups can't have different nitem.

Upvotes: 1

Views: 78

Answers (2)

abdusco
abdusco

Reputation: 11081

Override __new__ to perform checks upon object instantiation:

https://docs.python.org/3/reference/datamodel.html#object.new

from typing import Any


class foo(object):
    _groups = {}

    def __new__(cls, group, nitem) -> Any:
        if group not in cls._groups:
            cls._groups[group] = nitem
        if cls._groups[group] == nitem:
            return super().__new__(cls)
        raise ValueError('mismatched group and nitems')

    def __init__(self, group, nitem):
        self.group = group
        self.nitem = nitem


if __name__ == "__main__":
    a = foo(1, 100)
    b = foo(2, 10)
    c = foo(2, 100)

output:

Traceback (most recent call last):
  File "app.py", line 23, in <module>
    c = foo(2, 100)
  File "app.py", line 12, in __new__
    raise ValueError('mismatched group and nitems')
ValueError: mismatched group and nitems

it raises error when creating c

Upvotes: 1

jtan354
jtan354

Reputation: 104

Since there is a limited number of groups defined with a specific nitem number, you can simply use a dictionary with the key being the group name and item being the number of nitem that the group is allowed to have. Then in the constructor you can simply utilise the dictionary to allocate a default value to the nitem corresponding to the group.

An example is this:

group_dict = {"students": 5,
              "teachers": 10}

class foo(object):
    def __init__(self, group, nitem=group_dict[str(group)]):
        self.group = group
        self.nitem = nitem

Upvotes: 0

Related Questions