0

I want to define a subclass of a class, and I need it to be upgraded to in one of the class' methods, rather than initialized from the very beginning.

The example is a hobby project with Grids and the distances in them.
So I start a Grid class like this:

class Grid:
  def __init__(self):
    # A grid is a list of lists of cells. 
    self.grid = self.prepare_grid()
    self.configure_cells()
    self.maze = None

  def __getitem__(self, a_tuple):
    x, y = a_tuple
    return self.grid[x][y]

  def prepare_grid(self):
    ...

  def configure_cells(self):
    ...

Then I want to add Distance functionality. I was thinking like in a game where you've improved to became a Distance Grid, with methods like:

class DistanceGrid(Grid):
  def set_distances(self, root_cell):
    ...

  def path_to(self, goal):
    ...

Here comes the tricky part. Since I don't want it to be initialized, but rather improved to, I need a method on the parent class to make it a subclass (looks almost recursive, but hopefully it isn't).

from distances import DistanceGrid

class Grid: 
  ...

  def upgrade_distance(self, root):
    self = type(self, DistanceGrid)
    self.set_distances(root)

Can this be done? I'll keep trying. Thanks

4
  • 1
    Your logic escapes me... what are you trying to do? How is that going to be used? What do you mean "I don't want it to be initialized"? As far as I can see here, you're not initializing anything Commented Jun 6, 2018 at 10:33
  • It does not make sense to me to use distance related functions in Grid. Why is it not a DistanceGrid in the first place if you want to do that? Commented Jun 6, 2018 at 10:42
  • That's the tricky part. Distance isn't natural because it depends on a root cell, and this is arbitrary. Thus the whole DistanceGrid needn't be initialized to, but rather improved to with a choice of a root cell. Thank you for bearing with my logic. Commented Jun 6, 2018 at 10:49
  • 1
    The fact that there's a tricky part in a hobby project and other Pythonistas fail to see why that tricky part should even exist strongly hints that you have a design issue at hand. Restructure your program instead of searching for ugly hacks. Commented Jun 6, 2018 at 11:36

1 Answer 1

1

You say, "Since I don't want it to be initialized, but rather improved to, I need a method on the parent class to make it a subclass". Have you ever heard of composition as an alternative to inheritance? It would make it so that you have a method on the parent class to give it a DistanceGrid instance, as one of the class attributes. Something like this:

from distances import DistanceGrid

class Grid: 
  ...

  def upgrade_distance(self, root):
    self.distance_grid = DistanceGrid()
    self.distance_grid.set_distances(root)

The rest of the methods in the Grid class could either act on self.distance_grid if it is a method to be run after the upgrade, or ignore it if it's not needed. Maybe that would work for you?

Edit: You could also make 3 classes; 1-DistanceGrid, 2-Grid, 3-Choice, where the Choice class is the only one you create, it inherits from both of the other classes, and you decide which methods you want to call as you go.

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

1 Comment

Thanks. This is in the spirit of what I need. But I still need to finetune calling the methods and inheritence, that I wouldn't want to call from the composite object.

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.