理解类和__Call__方法Py 2.7

时间:2016-03-09 01:01:04

标签: python class python-2.x

好吧,我已经把我的前额用在了一些代码中,我已经确定我此刻只是在黑暗中拍摄。出于某种原因,让点击课程一直是一个真正的痛苦,我想如果我使用自己的个人代码,它可能是有道理的。所以这是我编写实验的一个小脚本游戏。 (非常粗糙我很新):https://github.com/Villagesmithy/Zombies-.git

我觉得要理解我做错了什么,我必须在我自己的代码中向我指出。有很多类似于我的问题我很确定,但他们很遗憾地过了我的脑袋。

我得到的错误是:

Attribute Error: Combat instance has no __Call__ method

以下是我认为是问题的课程:

class Combat:

    def battle(self): 

        print start.player, " has: ", hp, "."
        print "The zombie has: ", zombie.zom_health()
        time.sleep(1)

        if haf == True:

            total_damage = hero_attacks * hero_damage
            zombie.zom_health() - total_damage
            print "You strike the zombie for %d damage!" %(total_damage)
            print "The zombie's health is %d" %zombie.zom_health()
            return zombie.zom_health()              
            time.sleep(3)

        elif haf == False:
            total_damage = zombie.zom_damage()- hero.hero_armor()
            if total_damage > 0:
                total_damage - hp
                return hp
                print "A zombie shambles through the baricade and damages you!"
                print "You lost %d hp!  Your hp is now: %d" %(total_damage, hp)
                combat_loop()
                time.sleep(3)

            elif total_damage <= 0:
                print "A zombie lurches at you but misses!"
                time.sleep(3)
                combat_loop()

        else:
            z.zom_killed()

    def initv(battle):
        bat = battle()

        hero_init = random.randint(1,20)
        zom_init = random.randint(1,20)


        if hero_init >= zom_init:
            #global haf Ignoring for now
            haf = True
            print "You attack first!"
            bat.battle()
        elif hero_init < zom_init:
            #global haf
            haf = False
            print "The zombie attacks!"
            bat.battle()

    def start():  #The only fucking code that works
        global zombies
        zombies = random.randint(20,30)
        arm = random.sample(armor,1)
        wea = random.sample(weapon, 1)

        player = raw_input("What is your name?")
        print player, ",\n" 
        print "Your colony is under attack by %s zombies!" %(zombies)
        print "Hold them off so the others can escape."
        print "You are wearing an ", arm,  "and weilding a", wea
        time.sleep(3)



    def combat_loop():
        combat_call = Combat()

        while zombies > 0:
            combat_call.initv()

        if zombies <= 0:
            print "You held off the zombies off long enough to escape!"
            print "With the way clear you grab your belongings and follow suit."
            print "The end!"
            sys.exit()  

现在,如果你说Gee,这个孩子不知道他在做什么,那你就是对的!我只是希望你们可以帮我点击这个。整个计划可能需要在我不知道的赌注上烧掉。你能给予的任何帮助都会非常有帮助。

3 个答案:

答案 0 :(得分:3)

我假设initv实际上是Combat的一种方法,但您忘记将self作为参数,并为其指定一个名为battle的参数

当您致电bat.initv()时,它正在self传递battleself是约定的名称;方法的第一个位置参数是self无论你决定称之为什么)。因此,当您在bat = battle()中执行initv时,它与执行self()的操作相同,即尝试将您的类的实例视为可调用的。

据我所知,真正的目标是调用battle方法,因此initv的定义和第一行应为:

def initv(self):
    bat = self.battle()

在标准名称下传递self,然后在其上调用battle方法。有点不清楚battle方法返回的内容(似乎在两个代码路径上隐式返回None,并且在第三个代码路径上返回zombie.zom_health(),其中sleep返回return由于__call__取代它,它从未发生过,但是这段代码有很多问题,很难确定“正确”的行为是什么。

为了记录,错误几乎肯定会抱怨缺少__Call__方法,而不是{{1}}; the special method that lets instances of a class act as callables themselves is all lower case.

答案 1 :(得分:0)

combat_loop中,您将combat_call定义为Combat()。现在combat_callCombat的一个实例。然后在while循环中,您说combat_call.initv()。由于combat_callCombat的实例,因此Combat.initv(combat_call)的快捷方式。也就是说,combat_callinitv()的唯一参数。在initv()中,您可以使用一个参数:battle。在这种情况下,battlecombat_call的实例相同,Combatbat = battle()的实例。然后你说battleCombat已经是__call__的实例,因此您正在尝试调用实例。可以调用某些实例,但为此,他们需要定义battle方法。你的班级没有,所以有一个错误。我认为不要将self作为参数,而是采用bat。然后将self.battle()定义为{ "Subject": "Discuss the Calendar REST API", "Body": { "ContentType": "HTML", "Content": "I think it will meet our requirements!" }, "Start": { "DateTime": "2014-02-02T18:00:00", "TimeZone": "Pacific Standard Time" }, "End": { "DateTime": "2014-02-02T19:00:00", "TimeZone": "Pacific Standard Time" }, "Attendees": [ { "EmailAddress": { "Address": "janets@a830edad9050849NDA1.onmicrosoft.com", "Name": "Janet Schorr" }, "Type": "Required" } ] }

答案 2 :(得分:0)

还有一件事,除非您在zombie.zom_health() - total_damage课程中实施__sub__方法,否则我认为Zombie行无效。即便如此,我认为只有Zombie和Hero每个人都有相同的父级别说'Human'才有效。但我希望不是。 “有人”必须测试一下......在我为你的Hero课程测试更多修复之前,我需要先睡一觉。 :)也许Zombie - Hero可能有效。当对象(即Z1Z2)都来自Zombie类时,从Zombie类重新编写的这个示例工作正常。所以... Hero.total_damage()也可以正常工作。我还不确定。

import random

class Zombie:

    def __init__(self, zom_health=None):
        self.__zom_health = None
        if zom_health:
            self.__zom_health = zom_health
        else:
            self.randomize_zom_health()
        self.__zom_damage = 0

    def randomize_zom_health(self):
        zom_hp = random.randint(20,35)
        if zom_hp <= 0:
            print zom_killed
            self.__zom_health = 0
        else:
            self.__zom_health = zom_hp

    def __sub__(self, Other):
        self.__zom_health -= Other.zom_damage() #or Other.total_damage()?

    def zom_health(self):
        return self.__zom_health

    def zom_damage(self, damage=None):
        if damage: self.__zom_damage = damage
        return self.__zom_damage
>>> reload(Zombie)
>>> z1 = Zombie.Zombie(20)
>>> z2 = Zombie.Zombie(zom_health=30)
>>> z1.zom_health()
20
>>> z2.zom_health()
30
>>> z2.zom_damage(z2.zom_health())
30
>>> z1 - z2
>>> z1.zom_health()
-10
>>>