Python Forum

Full Version: calling on a method from one class into another class which is not a child
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I have a class called World, another one called Fish. Fish is not a child of World, and I want to call the method getMaxX() and getMaxY() into the Fish class, but I get attribute errors. How Can I Call getMaxX() and getMaxY() from World class into Fish class?

class World:
    def __init__(self, mX, mY):
        self.__maxX = mX
        self.__maxY = mY
        self.__thingList = []
        self.__grid = []
.....

    def getMaxX(self):
        return self.__maxX

    def getMaxY(self):
        return self.__maxY


#Now here is the Fish class

class Fish(LifeForm):
    def __init__(self):
        super().__init__("Fish.gif")
        
        self.__breedTick = 0
        self.__starveTick = 0
   ...

    def liveALittle(self):
        offsetList = [(-1,1), (0,1), (1,1),
                      (-1,0),        (1,0),
                      (-1,-1),(0,-1),(1,-1)]
        adjFish = 0  #count adjacent Fish
        for offset in offsetList:
            newX = self.getX() + offset[0]
            newY = self.getY() + offset[1]
            if 0 <= newX < ??????????????? and \
                  0 <= newY <????????????????????):
                if (not World.emptyLocation(newX, newY)) and \
                    isinstance(World.lookAtLocation(newX, newY), Fish):
                    adjFish = adjFish + 1

        if adjFish >= 2:   #if 2 or more adjacent Fish, die
            World.delThing()
        else:
            self.__breedTick = self.__breedTick + 1
            if self.__breedTick >= 12:  #if alive 12 or more ticks, breed
                self.tryToBreed()

...


What should go there instead of ??? I tried World.getMaxX(), self.__world.getMaxX(), etc. Nothing worked. I'm getting an attribute error saying the Fish doesn't have any world attribute or the missing positional argument:self error.
You cannot call Fish.getMaxX because Fish has no idea about how to do getMaxX. However, if fish has a World object (say world), Fish could call world.getMaxX()

So why doesn't Fish or Lifeform have maxX and maxY?
I don't know how to do it. So originally, there were World, Fish, Bear, and Plant class. I'm supposed to create a LifeForm class which would include the common methods for Fish and Bear and these two classes would inherit from LifeForm. World would be remained unchanged. World is drawing a grid since the result of the code is an animation of plants, bears, and fish and bear eating adjacent fish, etc....
You could make getMaxX and getMaxY class methods. Then you could call World.getMaxX(). However all instances of World would return the same value because it would be an attribute of the class, not the object.
But getMaxX returns self.__mX which is an attribute of the world. I don't know how to include that in LifeForm or Fish? Seem __ plays a role here. I cannot simply do World.getMaxX().
If getMaxX was a class method it would have to return a class variable.
class World:
    maxX = 100
    maxY = 100

    @classmethod
    def set_range(cls, mx, my)
        cls.maxX = mx
        cls.maxY = my


class Fish(LifeForm):
    def liveALittle(self)
        ...
        if 0 <= newX <= World.maxX:


def main():
    """Create everything"""
    World.setRange(10,000, 50,000)

    red_fish = Fish()
World could be a "class only" type class (My TM if nobody else has uses this), or it could be a regular class with some class attributes that are common to all instances.

If this pattern does not work for, you'll need to pass an instance of World to Fish. If all Fish are in the same World, the World attribute in Fish could be a class attribute.
class World:
    def __init__(self, mx, my):
        self.maxX = mx
        self.maxY = my


class Fish(LifeForm):
    world = None

    @classmethod
    def set_world(cls, world):
        cls.world = world

    def liveALittle(self)
        ...
        if 0 <= newX <= self.world.maxX:


def main():
    """Create everything"""
    world = World(10,000, 50,000)

    Fish.set_world(world)
    red_fish = Fish()