Reputation: 2801
Consider the class below:
class cell:
X_size = 10
Y_size = 10
world = np.zeros((X_size,Y_size))
I want to change the class above into the code below and be able to pass X_size, Y_size
to an instance:
class cell:
world = np.zeros((X_size,Y_size))#X_size and Y_size must be passed on the run time
I could do:
class cell:
def __init__(self, X_size,Y_size):
self.X_size = X_size
self.Y_size = Y_size
world = np.zeros((X_size,Y_size))
The problem is that then every instance makes a new world
. I want the world
to be created once, to be seen by all the instances and then each new instance modify only one of the world's elements which also could be seen by all the other instances. That is why I use the class variable, but then if I use the class variable, it seems I have to determine X_size
and Y_size
before hand.
Upvotes: 0
Views: 67
Reputation: 336
To pass arguments to class declarations, one must declare either a superclass with __init_subclass__
(see here) or a metaclass.
__init_subclass__
is the most straight forward way to achieve what you are describing:
class BaseCell:
def __init_subclass__(cls, *, X_size, Y_size):
cls.world = np.zeros((X_size, Y_size))
This allows you to pass the size arguments to subclasses of BaseCell
, like so:
class MyCell(BaseCell, X_size=10, Y_size=10):
pass
cells = [MyCell(), MyCell()]
assert cells[0].world is cells[1].world
assert len(cells[0].world) == 10
assert len(cells[0].world[0]) == 10
Then all instances of MyCell
will share a single world
class attribute, with width 10 and height 10.
Note: Depending on the wider context of what you are trying to achieve, it might be that simply passing the world
to each instance constructor might be a more suitable approach (see dependency inversion).
Upvotes: 3