Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python OOP - Class relationships

Tags:

python

oop

Assuming I have a system of three Classes. The GameClass creates instances of both other classes upon initialization.

class FieldClass:
    def __init__( self ):
        return
    def AnswerAQuestion( self ):    
        return 42

class PlayerClass:
    def __init__( self ):
        return
    def DoMagicHere( self ):
        # Access "AnswerAQuestion" located in the "FieldClass" instance in "GameClass"
        pass

class GameClass:
    def __init__( self ):
        self.Field = FieldClass()
        self.Player = PlayerClass()

What would be the best way of accessing AnswerAQuestion() located in FieldClass from within the instance of PlayerClass?

  • Do I have to pass a reference to the FieldClass instance to PlayerClass?
  • Is there another, better way of solving this? Doing the above would make me have to include an additional variable in PlayerClass to hold the FieldClass instance.
  • Is there a completely different way of managing class relationships in Python?
like image 582
lamas Avatar asked Feb 24 '10 17:02

lamas


2 Answers

I would go with Dependency Injection: instantiate a GameClass with the required FieldClass and PlayerClass in the constructor call etc. (i.e. instead of creating the dependent objects from within GameClass as you are doing at the moment).

class GameClass:
    def __init__( self, fc, pc ):
        self.Field = fc
        self.Player = pc

class PlayerClass:
    def __init__( self, fc ):
        self.fc = fc

    def DoMagicHere( self ):
        # use self.fc
        pass

fc=FieldClass()
pc=PlayerClass(fc)
gc=GameClass(fc, pc)

With DI, you can easily have access to the members you require once the setup phase is completed.

like image 135
jldupont Avatar answered Sep 20 '22 04:09

jldupont


To better understand your class relationships you have to tell us more about your project and what you are trying to accomplish.

One way to reference the instance of FieldClass from PlayerClass in your example is to pass the GameClass instance to the PlayerClass instance:

class PlayerClass:
    def __init__(self, game):
        self.game = game
    def DoMagicHere(self):
        self.game.Field.AnswerAQuestion()

# ...

class GameClass:
    def __init__( self ):
        self.Field = FieldClass()
        self.Player = PlayerClass(self)

Another way is to pass the field variable

class PlayerClass:
    def __init__(self, field):
        self.field = field
    def DoMagicHere(self):
        self.field.AnswerAQuestion()
# ...

class GameClass:
    def __init__( self ):
        self.Field = FieldClass()
        self.Player = PlayerClass(self.Field)

As a side note: you use a peculiar naming scheme. I suggest this:

 class Game:
     def __init__(self):
         self.field = Field()
         self.player = Player(...)

I suggest you read the Python Style Guide before acquiring bad habits.

like image 29
Otto Allmendinger Avatar answered Sep 23 '22 04:09

Otto Allmendinger