Question

For some reason, the class variable self cannot be defined in a function.

Function:

def pickapoo_specialattack(opponent):
    print("PICKAPOO's FLATULENCE BOLTS WAS EFFECTIVE")
    self.damage -= float(self.damage / 20)
    damage_dealt = random.randrange(200, 250)
    defender.health -= damage_dealt
    print("\nPICKAPOO's DAMAGE RATING WAS DECREASED BY 20%")
    print("PICKAPOO's DAMAGE RATING IS NOW {}".format(str(self.damage)))
    return self.damage

Class:

class Deskemon(object):
    def __init__(self, name, health, damage, defense):

        self.base_name = name
        self.base_health = health
        self.base_damage = damage
        self.base_defense = defense

        self.name = self.base_name
        self.health = self.base_health
        self.damage = self.base_damage
        self.defense = self.base_defense

Traceback:

Traceback (most recent call last):
  File "DESKEMON PRE ALPHA.py", line 378, in <module>
    Battle(deskemon, Jack)
  File "DESKEMON PRE ALPHA.py", line 168, in Battle
    Deskemon_Attack(D1, D2, special=(random.randrange(1, 100) <= 45))            
  File "DESKEMON PRE ALPHA.py", line 216, in Deskemon_Attack
    pickapoo_specialattack(defender)
  File "DESKEMON PRE ALPHA.py", line 115, in pickapoo_specialattack
    self.damage -= float(self.damage / 20)
NameError: name 'self' is not defined

Here is my full code: http://pastebin.com/8Xn6UCKS

Was it helpful?

Solution

that's because the self variable has to be explicitely given to methods in python. As you write it, are you expecting python to read your mind so it guesses that self shall be something from a class your function is not related at all with?

So to have it bound you need:

  1. add self to argument list of def pickapoo_specialattack(self, opponent)
  2. to move pickapoo_specialattack(opponent) in your Deskemon class

looking further in your code, what you're doing is definitely wrong, as you're defeating the whole purpose of OOP! Use classes and subclasses to do what you're aiming.

Let me give you an incomplete example of what I mean:

class Deskemon(object):
    def specialattack(self, opponent):
        raise NotImplementedError

    …

class Pickapoo(Deskemon):
    def specialattack(self, opponent):
         … # content of the pickapoo_specialattak() function

class Tamosha(Deskemon):
    def specialattack(opponent):
         … # content of the tamosha_specialattak() function

and then:

def main():
    pickapoo = Pickapoo(…)
    tamosha = Tamosha(…)

instead of monkey patching Deskemon instances, use proper OOP conception and make Deskemon the base class of all your instances. Then you create a specialized instance for each Deskemon object, and that's the thing you initialize.

N.B.1: you should init all your objects in a main function:

N.B.2: you should place all your code at the end in a main function:

def main():
    # init
    pickapoo = Pickapoo(…)
    tamosha = Tamosha(…)
    lilwilly = Lilwilly(…)
    bigbboy = Biggboy(…)

    # start up
    print("Welcome to Deskemon Pre-Alpha V1.2".upper())
    …

    # play loop
    while True:
        deskemon_selection_menu()
        deskemon_selection_input = input("> ")
        if deskemon_selection_input == "1":
            deskemon = tamosha
        elif deskemon_selection_input == "2":
            deskemon = pickapoo
        elif deskemon_selection_input == "3":
            deskemon = lilwilly
        elif deskemon_selection_input == "4":
            deskemon = biggboi
        else:
            continue
        print("You have selected {} as your Deskemon".upper().format(deskemon))
        break

    # shut down
    print("Professor Andrew: Alright Jack, it's time to pick your Deskemon.")
    …
    print("Jack: OI! " + name + "!")
    time.sleep(1)

    Battle(deskemon, Jack)

if __name__ == "__main__":
    main()
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top