简体   繁体   English

在python中,窃取B类方法并将其用作A类方法中的A类实例

[英]In python, steal a class B method AND use it as an instance of class A from within a class A method

I've been successfully able to "spellsiphon" (steal) a method from one class (darkMage) to give to the player class (Player). 我已经成功地能够“拼写”(窃取)一个类(darkMage)中的方法,并将其提供给玩家类(Player)。

However, the "stolen" method still seems to belong to the darkMage class--in other words, when the Player casts the stolen spell, it still reads (in all ways) as the darkMage casting the spell. 但是,“被盗”方法似乎仍然属于darkMage类-换句话说,当玩家施放被盗的咒语时,它仍然(在所有方面)读取为DarkMage施放该咒语。

Can you help? 你能帮我吗? I've done this: 我已经做到了:

  • Added the stolen darkMage() spell to the Player's spellbook (a list) 将被盗的darkMage()法术添加到玩家的法术书(列表)中
  • Successfully paired the "cast" command with items in the spellbook 成功将“ cast”命令与拼写簿中的项目配对

I want to: - Have the Player() casting the spell rather than the darkMage (when the stolen method is called, it's run as the darkMage rather than the Player) 我想要:-让Player()投放咒语而不是darkMage(当调用被盗方法时,它将作为DarkMage而不是Player运行)

class Player(livingThing):
    def __init__(self,name="The Stranger", HP=10, MP=5, strength=1, intellect=1, spirit=1, luck=5, gil=6):
        self.name = name
        self.HP = HP
        self.MP = MP
        self.gil = gil
        self.strength = strength
        self.intellect = intellect
        self.spirit = spirit
        self.luck = luck
        self.spellbook = []

    def act(self, enemy):
        actions = {
        "a" : self.attack, 
        "heal" : self.heal, 
        "flee" : self.flee,
        "cast" : self.cast,
        "siphon" : self.spellsiphon
        }
        #Takes input from the player
        self.safe = False
        while ((self.HP > 0) and (enemy.HP > 0)) and (self.safe != True):
            decision = input("What would you like to do? ")

            #Sets the user's input as lower-case and checks for it within the dictionary
            if decision.lower() in actions:
                actions[decision.lower()](enemy)
                if self.safe != True:
                    enemy.agreact(self)
                    self.printHP(enemy)

            else:
                print("That didn't workkkkkk!  Try again.")

    # Prints both player and enemy HP
    def printHP(self, enemy):
        print("{0}'s' HP: {1} \n{2}'s HP: {3}".format(self.name, self.HP, enemy.name, enemy.HP))

    # Allows the player to attack an enemy (currently functional)
    def attack(self, enemy):
        enemy.HP -= self.strength
        print("You strike {0} for {1} damage!".format(enemy.name, self.strength))
        #player.printHP(enemy)

    # Allows the player to heal a certain amount of health based on its "spirit" stat (currently functional)
    def heal(self, enemy):
        healed = randint(0, self.spirit)
        self.HP += healed
        print("You've healed for {0}!".format(healed))
        #player.printHP(enemy)

    #Allows the player to attempt to run away
    def flee(self, enemy):
        randluck = randint(0, self.luck)
        if randluck > 3:
            print("You successfully escaped!")
            self.safe = True
        else:
            print("You weren't able to escape!")

    def cast(self, enemy):
        if len(self.spellbook) != 0:
            spellchoice = randint(0, len(self.spellbook)-1)
            self.spellbook[spellchoice](self)
        else:
            print("You don't have any spells to cast!")

### SPELLSIPHON IS CURRENTLY BROKEN; IT -DOES- SIPHON THE SPELL BUT ONLY ALLOWS THE DARK MAGE TO CONTINUE CASTING ###
    def spellsiphon(self, enemy):
        if len(enemy.spellbook) != 0:
            randspell = randint(0, len(enemy.spellbook)-1)
            stolenspell = darkMage().spellbook[randspell]
            #(type(enemy).__name__).__init__(self, stolenspell)
            self.spellbook.append(stolenspell)
            print("You've successfully stolen {0} from {1}!".format("stolenspell", enemy.name))
        else:
            print("You can't steal a spell from {0}!".format(enemy.name))


# Anything that can act with/against the player
class Actor(livingThing):
    def __init__(self, name="Unknown Entity", HP=10, MP=2, strength=1, intellect=1, spirit=3, gil=3):
        self. name = name
        self.HP = HP
        self.MP = MP
        self.gil = gil
        self.strength = strength
        self.intellect = intellect
        self.spirit = spirit
        self.abilities = [self.strike, self.heal]
        def printabilities():
            print(self.abilities)

    # Chooses how your opponent will respond to your attack
    def agreact(self, player):
        choice = randint(0, len(self.abilities)-1)
        self.abilities[choice](player)

    # A basic "hit back" reaction from your opponent--everyone can do this
    def strike(self, player):
        player.HP -= self.strength
        print("{0} hit {1} for {2}!".format(self.name, player.name, self.strength))

    def heal(self, enemy):
        healed = randint(0, self.spirit)
        self.HP += healed
        print("{0} healed for {1}!".format(self.name, healed))


### CURRENT VERSION SUPPORTS THE ADDITION OF NEW ABILITIES IN CHILD CLASSES VIA THE "super().__init__()" method! ###
class Enemy(Actor):
    def __init__(self):
        super().__init__()
        self.abilities.append(self.cast)
        self.name = "Unknown Enemy"
        self.HP = 600
        self.spellbook = []
    def cast(self, opponent):
            if len(self.spellbook) != 0:
                spellchoice = randint(0, len(self.spellbook)-1)
                self.spellbook[spellchoice](opponent)

class darkMage(Enemy):
    def __init__(self):
        super().__init__()
        self.player = Player()
        self.name = "Dark Mage"
        self.spellbook.extend((self.fireball, self.icenova))
    def fireball(cls, opponent):
        choice = randint(cls.intellect*1, cls.intellect*2)
        spellname = "Fireball"
        opponent.HP -= choice
        print("{0} casted fireball for {1} damage!".format(cls.name, choice))
    def icenova(cls, opponent):
        opponent.HP -= cls.intellect
        choice = randint(0,1)
        name = "Ice Nova"
        if choice == 1:
            frozen = True
        else:
            frozen = False
        print("{0} casted ice nova for {1} damage!".format(cls.name, cls.intellect))
        if frozen == True:
            print("{0} has been frozen solid!".format(opponent.name))

It looks like you want the spells to be detached from the enemies/players. 您似乎希望将咒语与敌人/玩家分离。 You can do this by making them static methods instead of instance methods (you're using def fireball(cls,..) but not using the @classmethod decorator, so they are really instance methods). 您可以通过使它们成为静态方法而不是实例方法来实现此目的(您正在使用def fireball(cls,..) ,但未使用@classmethod装饰器,因此它们实际上是实例方法)。 Static methods don't automatically get passed the class/instance they are attached to like class/instance methods, so you can pass they can be 'stolen' and 'cast' (called) without remembering the original owner. 静态方法不会像类/实例方法那样自动传递它们所附加的类/实例,因此您可以在不记住原始所有者的情况下将它们“窃取”和“铸造”(调用)传递。

Here is a simple example: 这是一个简单的示例:

class DarkMage:
    def __init__(self, name):
        self.name = name
        self.spellbook = [self.fireball]

    @staticmethod
    def fireball(caster, target):
        print("{} casted fireball on {} for 10 damage".format(caster.name, target.name))


class Player:
    def __init__(self, name):
        self.name = name
        self.spellbook = []

    def spellsiphon(self, enemy):
        if enemy.spellbook:
            spellchoice = randint(0, len(enemy.spellbook)-1)
            self.spellbook.append(enemy.spellbook[spellchoice])

    def cast(self, enemy):
        if self.spellbook:
            spellchoice = randint(0, len(self.spellbook)-1)
            self.spellbook[spellchoice](self, enemy)

>>> dm = DarkMage('Bad Guy')
>>> p = Player('Do-Gooder')
>>> p.spellsiphon(dm)
>>> p.cast(e)
Do-Gooder casted fireball on Evildoer for 10 damage
>>> p.cast(dm)
Do-Gooder casted fireball on Bad Guy for 10 damage

You can also define the static methods outside the classes, which would let you share them between classes a bit easier, but I think the ideal way to do this would be to make spells their own python classes so that you can attach names and other attributes to them: 您还可以在类外部定义静态方法,这使您可以在类之间共享它们,但是我认为,实现此目的的理想方法是使自己的python类具有拼写功能,以便可以附加名称和其他属性给他们:

class Fireball:
    name = 'fireball'
    damage = 10

    @classmethod
    def cast(cls, caster, target):
        print(
            '{} cast {} on {} for {} damage!'.format(
                caster.name,
                cls.name,
                target.name,
                cls.damage,
            )
       )

class SuperFireball(Fireball):
    name = 'super fireball'
    damage = 50

class Player:
    def __init__(self):
        self.spellbook = [Fireball]

    def list_spells(self):
        for spell in self.spellbook:
            print(spell.name)

    def cast(self, enemy):
        if self.spellbook:
            spellchoice = randint(0, len(self.spellbook)-1)
            self.spellbook[spellchoice].cast(self, enemy)

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

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