0

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.

4
  • I believe you can just do cell.world = ... later on. Also, you should name your classes capitalized. Commented Jan 11, 2021 at 13:21
  • 1
    If each instance can have its own independent world size, how can there be a single world that is shared by all instances? Commented Jan 11, 2021 at 13:22
  • @mkrieger1 I am trying to understand if it is possible to determine the class variable's value during runtime. Your objection is true, all the instances should have the same size world. Then perhaps, what I try to do is not possible or good programing habits in Python? Commented Jan 11, 2021 at 13:24
  • 1
    "I am trying to understand if it is possible to determine the class variable's value during runtime." That's possible and normal, but what you are proposing specifically doesn't make a lot of sense. How is each instance supposed to have a separate value for X_size and Y_size, and at the same time, the class variable is supposed to be initialized depending on that value? Unless you mean to change the world size everytime a cell is instantiated? Commented Jan 11, 2021 at 13:30

1 Answer 1

3

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).

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.