该计划相当不言自明。我已经开始玩Python的基础知识,我真的迷失了这个。我习惯了C ++以及通过引用传递东西的奇妙能力。但是,在这里,我试图改变的类变量(Fighter.statHEALTH)不会改变,我读到它是因为整数是不可变的,它只是在本地创建一个新对象。那么我可以在世界上如何将更改应用于原始变量?我用谷歌搜索和谷歌搜索,但无济于事。我不想执行一些丑陋的操作,比如制作一个列表并传递它,如果我不需要的话。
#python 3.2.2
# Create a small test project to have combat between two entities. #
# Combat should include 3 different stats: statATK, statDEF, and statHEALTH. #
# The two entities should be of the same class. #
class Fighter:
def __init__(self):
self.statHEALTH = 10
self.statATK = 3
self.statDEF = 3
def attack(self, enemyhealth):
enemyhealth = (enemyhealth - self.statATK)
return enemyhealth
def defend(self):
statDEF += 1
def main():
James = Fighter()
Keaton = Fighter()
while James.statHEALTH > 0:
print("Do you wish to attack or defend?")
print("1. Attack")
print("2. Defend")
choice = input()
if choice == "1":
James.attack(Keaton.statHEALTH)
print("You did", James.statATK, "damage!")
Keaton.attack(James.statHEALTH)
print("Keaton has", Keaton.statHEALTH, "health left.")
print("Keaton did", Keaton.statATK, "damage!")
print("You have", James.statHEALTH, "health left.")
#elif choice == "2":
#James.defend()
#Keaton.attack(James.statHEALTH)
main()
答案 0 :(得分:3)
def attack(self, enemyhealth):
enemyhealth = (enemyhealth - self.statATK)
return enemyhealth
如果您将通话更改为
,这实际上会有效Keaton.statHEALTH = James.attack(Keaton.statHEALTH)
..因为你return
来自攻击造成的伤害。显然这很难看;重复自己并不好。相反,您可以使attack
看起来像:
def attack(self, other):
other.statHEALTH -= self.statATK
然后就这样做
James.attack(Keaton)
当你打电话时。
答案 1 :(得分:1)
也许你可以用不同的方式来思考它。在您的示例中,Fighter.attack()
只会在攻击后返回敌人的健康值。所以,它应该是对敌人物体的方法调用。您可以添加一种方法,在受到攻击时降低战斗机的健康状况:
def attack(self, enemy):
enemy.getAttacked(self.statATK)
def getAttacked(self, ATK):
self.statHEALTH -= ATK
答案 2 :(得分:1)
尝试做:
while James.statHEALTH > 0:
#print statements
if choice == "1":
the_attack = James.attack(Keaton)
然后将您的类定义为:
class Fighter(object):
def __init__(self):
self.statHEALTH = 10
self.statATK = 3
self.statDEF = 3
def attack(self,target):
attack_details = target.takedamage(self.statATK)
return attack_details
def takedamage(self,dmg):
modified_dmg = dmg-self.statDEF
self.statHEALTH -= modified_dmg
return modified_dmg
这具有易于扩展的额外好处,例如,你可以为某些元素添加一个命中表(for i in random.randint(1,100) if i < 20: #miss; elif 20 <= i < 80: #hit; elif 80<= i: #crit
)或阻力,或者添加一个标志,允许你的后卫在他们的takedamage
函数中进行反击(可能会调用一个新函数getcountered
来防止无限循环)。
答案 3 :(得分:1)
问题不在于您无法通过Python中的引用传递内容。实际上,您总是通过引用传递值;除非你要求,否则Python永远不会复制值。
或者更确切地说,整个基于C的术语在Python中具有误导性。
无论如何,当你这样做时:
James.attack(Keaton.statHEALTH)
这不会复制Keaton.statHEALTH
中的值,它会将引用传递给完全相同的值。因此,当attack
开始时,您的enemyhealth
变量就是该值的名称。
然后你这样做:
enemyhealth = (enemyhealth - self.statATK)
... enemyhealth - self.statATK
返回一个新值,然后将该新值绑定到enemyhealth
名称。这对旧值的任何其他名称都没有影响。
有两种方法可以解决这个问题。
首先,你实际上并不需要需要来改变任何东西。你最后已经在做return enemyhealth
了。这意味着调用者可以获得您计算的新值。那么为什么不用它?
Keaton.statHEALTH = James.attack(Keaton.statHEALTH)
然后一切正常。
当然在C ++中,您可以改变整数值。当你想到它时,这似乎有点傻 - 将数字24转换为数字19会破坏大量数学,并且可能使宇宙停止工作,而Python就不那么强大了。
但是你可以轻松地构建一个可以明显变异的类型。实际上,您已经构建了一个:Fighter
保存整数运行状况值,但可以更改为保持不同的值。所以,你可以这样写:
def attack(self, enemy):
enemy.health = enemy.health - self.statATK
然后:
James.attack(Keaton)
正如调用使用Keaton.health
的旧方法将enemyhealth
转换为对同一号码的另一个引用一样,使用Keaton
调用新方法会使enemy
成为对Fighter
的引用相同enemy
。如果您刚刚将新值重新分配给Keaton
,则不会对旧值(Keaton
引用的值)产生任何影响。但是,如果您就地更改了值,显然{{1}}仍然指的是现在更改的值。