繁体   English   中英

Python如何将类函数从实例传递给另一个类

[英]Python how to pass class function from instance to another class

我有一类具有许多属性的Player来衡量他们的整体状态。 我有第二类Character (类类型),根据他们的角色实例为我的玩家设置一些独特的配置。 我遇到麻烦的地方是在玩家级别调用一个通用函数来衡量每个角色的独特里程碑目标。 即检查每个玩家,看看他们是否达到了他们唯一的里程碑 1。我最初尝试在初始化下使用一系列条件函数来做到这一点,但事实证明这在类中是不明智的,所以我把它移到了它的自己的单一功能。 由于这样做,它显然失败了,因为函数正在检查的属性在父类( Player )中,而不是在定义函数的类( Character )中。

class Player:
    def __init__(self, player_num, name):
        self.character = Character(name)
        self.player_num = player_num
        self.name = name
        self.power = 0
        self.position = 1
        self.attributeLimit = 4
        self.attributes = []
        self.attachments = []
        self.collection = []
        self.visited = []
        self.setCharacterValues()
        self.ms1 = self.character.Milestone1 

        def setCharacterValues()
        #Loads Character instance data into the Player instance.

class Character:
    def __init__(self, name):
        self.attributes = []
        self.attachments = []
        self.collection = []
        self.visited = []
        self.name = name
        if name == 'char x':
            self.attributes = [1,2,3]
            #etc.
        #etc.

    def Milestone1(self):
        if self.name == 'char x':
            if self.power >= 20:
                return True
            else:
                return False
        if self.name == 'char y':
            if self.position >= 5:
                return True
            else:
                return False
        #etc

for i in players:
    if i.ms1():
        print('Passed')

现在我能想到的唯一解决方案是简单地将函数从Character类移动到Player类。 但这对我来说似乎有违直觉,因为这个功能是衡量每个独特角色达到里程碑的能力。 将它留在 Character 下感觉很合适,而我只是在某处遗漏了一个明显的步骤。 任何人都可以提供一些帮助吗?

请发布回溯错误消息。 我认为问题在于Milestone1()您检查self.powerself.position但 self 指的是Character而不是Player的实例,并且 character 没有 power 或 position 属性。

以下是我能想到的 2 个修复:

  1. 继承:如果你让玩家成为角色的子类,那么玩家将拥有角色的所有属性,因此能够调用ms1()

     class Player(Character): def __init__(self, player_num, name): # self.character = Character(name) <-- not needed # self.ms1 = self.character.Milestone1 <-- not needed # since Player is a subclass of Character, # use super to init & it already has name and Milestone1 super().__init__(name) # Py3 usage # super(Player, self).__init__(name) # Py2 usage

    在 repl.it 上的一个简单示例中对此进行了测试,它对我有用,按 play 试试,输出是'n' ,然后是't'

    注意:在 Python-2 中, super的语法与 Python-3 不同,您还必须提供子类Player和实例self作为参数。 使用 Python-2这个示例 repl.it 中使用super(Player, self).__init__(name)测试了继承,它也可以工作。

    另请注意: Python-2 类应该子类化object以创建新样式类

  2. 组成:修复Milestone1()使其使用玩家作为参数,因此可以访问权力和位置

    class Character: # no change def Milestone1(self, player): if self.name == 'char x': if player.power >= 20: return True else: return False

    也更新Player ,将播放器实例传递给Milestone1

     class Player: def __init__(self, player_num, name): self.character = Character(name) # self is the Player, lambda makes ms1 callable self.ms1 = lambda: self.character.Milestone1(self)

    虽然那时name属性并没有真正使用,这似乎有点hacky,但我在这个简单的 repl.it 示例中对其进行了测试,它也有效。

总的来说,我认为这是一个使用继承而不是组合的好机会。 问你自己:

玩家是角色吗? (继承:#1)

玩家有角色吗? (组成:#2)

我也建议在 Character 类中初始化一个 power 值,或者在 Character 类中创建一个通用方法,然后在 Player 类中覆盖它。

您拥有的是一个与Character具有一对一关系的容器类Player 您不想复制 Character 的属性(例如Player ms1 ,尤其是在__init__期间不要在游戏中发生任何事情之前。而是在需要检查时从 Player 实例访问该 Character 的属性:

player = Player(player_num=42, name='Ivan')
# do some stuff with `player` and `player.character` as the game progresses
# then somewhere deep in the game...
if player.character.ms1:
    print("Congratulations on achieving your first milestone!")

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM