You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中攻击类方法如何访问调用者(英雄/怪物)的属性?

问题核心原因

你当前的代码里,attacks.hit是绑定到Attacks实例的方法,当把它赋值给my_hero.attack后,调用my_hero.attack(my_monster)时,方法里的self仍然指向Attacks实例,而不是Hero实例,自然找不到strength属性。

下面是几种可行的解决方法:


方法1:让角色类继承攻击类(最直观的面向对象方案)

让Hero和Monster直接继承Attacks,这样攻击方法里的self就指向角色实例,能直接访问strength:

class Attacks:
    def bite(self, who):
        print('I bite')
        who.health -= self.strength
    def hit(self, who):
        print('I hit')
        who.health -= self.strength

class Hero(Attacks):
    def __init__(self, health, strength):
        self.health = health
        self.strength = strength
        # 给角色指定默认攻击方式
        self.attack = self.hit

class Monster(Attacks):
    def __init__(self, health, strength):
        self.health = health
        self.strength = strength
        self.attack = self.bite

# 测试代码
my_hero = Hero(100, 10)
my_monster = Monster(100, 10)

print(my_monster.health)  # 输出100
my_hero.attack(my_monster)
print(my_monster.health)  # 输出90

这种方案符合"角色具备攻击能力"的逻辑,代码简洁,不需要额外的绑定操作。


方法2:将攻击方法改为静态方法,传入攻击者参数

把Attacks里的方法改成静态方法,不需要依赖Attacks实例的self,而是直接接收攻击者和目标两个参数,再在角色初始化时用lambda把自身绑定进去:

class Attacks:
    @staticmethod
    def bite(attacker, who):
        print('I bite')
        who.health -= attacker.strength
    @staticmethod
    def hit(attacker, who):
        print('I hit')
        who.health -= attacker.strength

class Hero:
    def __init__(self, health, strength, attack):
        self.health = health
        self.strength = strength
        # 包装攻击方法,让调用时只需要传目标
        self.attack = lambda who: attack(self, who)

class Monster:
    def __init__(self, health, strength, attack):
        self.health = health
        self.strength = strength
        self.attack = lambda who: attack(self, who)

# 测试代码
attacks = Attacks()
my_hero = Hero(100, 10, attack=attacks.hit)
my_monster = Monster(100, 10, attack=attacks.bite)

print(my_monster.health)  # 输出100
my_hero.attack(my_monster)
print(my_monster.health)  # 输出90

这种方案的优势是攻击逻辑和角色完全解耦,你可以随时给角色替换不同的攻击方法,甚至新增攻击方式也不需要修改角色类。


方法3:用functools.partial绑定攻击者(更优雅的包装方式)

和方法2类似,不过用functools.partial替代lambda,代码可读性更好:

from functools import partial

class Attacks:
    def bite(self, attacker, who):
        print('I bite')
        who.health -= attacker.strength
    def hit(self, attacker, who):
        print('I hit')
        who.health -= attacker.strength

class Hero:
    def __init__(self, health, strength, attack):
        self.health = health
        self.strength = strength
        # 把当前角色实例绑定到攻击方法的第一个参数
        self.attack = partial(attack, self)

class Monster:
    def __init__(self, health, strength, attack):
        self.health = health
        self.strength = strength
        self.attack = partial(attack, self)

# 测试代码
attacks = Attacks()
my_hero = Hero(100, 10, attack=attacks.hit)
my_monster = Monster(100, 10, attack=attacks.bite)

print(my_monster.health)  # 输出100
my_hero.attack(my_monster)
print(my_monster.health)  # 输出90

内容的提问来源于stack exchange,提问作者Richard

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 15:12:47