Python面向对象编程 - 类之间关系
假设我有一个包含三个类的系统。GameClass
在初始化时会创建另外两个类的实例。
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()
那么,从 PlayerClass
的实例中,访问位于 FieldClass
中的 AnswerAQuestion()
方法,最好的方法是什么呢?
- 我是否需要把
FieldClass
的实例传递给PlayerClass
? - 有没有其他更好的解决办法?这样做的话,我就得在
PlayerClass
中多加一个变量来保存FieldClass
的实例。 - 在 Python 中,有没有完全不同的方式来管理类之间的关系?
4 个回答
1
你可以给子对象提供一些上下文,也就是说:
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)
因为这些对象知道它们的上下文,所以它们可以进入这个上下文,访问同一上下文中的其他对象。
4
为了更好地理解你们的类之间的关系,你需要告诉我们更多关于你的项目以及你想要实现的目标。
在你的例子中,有一种方法可以让PlayerClass
引用FieldClass
的实例,就是把GameClass
的实例传递给PlayerClass
的实例:
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)
另一种方法是直接传递field
这个变量。
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)
顺便提一下,你的命名方式有点特别。我建议你这样做:
class Game:
def __init__(self):
self.field = Field()
self.player = Player(...)
我建议你在养成坏习惯之前,先看看Python风格指南。
6
我建议使用依赖注入:在创建一个GameClass
的时候,把需要的FieldClass
和PlayerClass
作为参数传进去。也就是说,不要像现在这样在GameClass
内部创建这些依赖的对象。
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)
使用依赖注入后,一旦设置完成,你就可以轻松访问所需的成员了。