Reputation: 2553
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
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
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