2010-02-24 10 views
8

Suponiendo que tengo un sistema de tres clases. El GameClass crea instancias de las otras dos clases en la inicialización.Python OOP - Relaciones de clase

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

¿Cuál sería la mejor manera de acceder a AnswerAQuestion() situado en FieldClass desde dentro de la instancia de PlayerClass?

  • ¿Tengo que pasar una referencia a la instancia FieldClass a PlayerClass?
  • ¿Hay alguna otra forma mejor de resolver esto? Hacer lo anterior me obligaría a incluir una variable adicional en PlayerClass para contener la instancia FieldClass.
  • ¿Existe una forma completamente diferente de gestionar las relaciones de clase en Python?

Respuesta

6

Me gustaría ir con Dependency Injection: una instancia de un GameClass con la requerida FieldClass y PlayerClass en la llamada al constructor, etc (es decir, en lugar de crear los objetos dependientes de dentro GameClass como lo están haciendo en este momento).

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) 

Con DI, puede acceder fácilmente a los miembros que necesita una vez que se completa la fase de configuración.

4

Para comprender mejor las relaciones de su clase, tiene que decirnos más sobre su proyecto y lo que está tratando de lograr.

Una forma de hacer referencia a la ejemplo de FieldClass de PlayerClass en su ejemplo es pasar la instancia GameClass a la PlayerClass ejemplo:

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) 

Otra manera es pasar la field variable de

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) 

Como nota al margen: utiliza un esquema de nombres peculiar. Sugiero esto:

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

le sugiero que lea el Python Style Guide antes de adquirir malos hábitos.

+0

Gracias por la información sobre el problema del esquema de nombres – lamas

+1

+1 para la sugerencia de mejorar los nombres de las clases. –

0

Haría algo como lo siguiente, donde pasaría Game in como referencia, permitiéndole acceder a las otras clases asociadas. De esta forma, podría opcionalmente darle a esa instancia de jugador una relación directa con el campo.

class FieldClass(object): 
    def __init__(self, game): 
     self.Game = game 
    def AnswerAQuestion(self):  
     return 42 

class PlayerClass(object): 
    def __init__(self, game): 
     self.Game = game 
     self.Field = game.Field # Optional 
    def DoMagicHere(self): 
     self.Game.Field.AnswerAQuestion() 
     self.Field.AnswerAQuestion() # Optional 

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

Una nota es que es una buena práctica ahora para tener todas sus clases heredar de object en lugar de tenerlos por sí solo.

1

Usted puede proporcionar el contexto de los objetos secundarios, es decir .:

class FieldClass: 
    def __init__(self,game): 
    self.game = game 

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) 
    self.Player = PlayerClass(self) 

Dado que los objetos conocen su contexto se puede alcanzar en él y acceder a otros objetos en el mismo contexto.