TypeError: __init __ () toma al menos 2 argumentos (1 dado) error

Estoy desarrollando un juego de Dungeon basado en texto simple utilizando Python3. Primero se le pide al usuario que seleccione el héroe del archivo screen.py.

from game import * class GameScreen: '''Display the current state of a game in a text-based format. This class is fully implemented and needs no additional work from students.''' def initialize_game(self): '''(GameScreen) -> NoneType Initialize new game with new user-selected hero class and starting room files.''' hero = None while hero is None: c = input("Select hero type:\n(R)ogue (M)age (B)arbarian\n") c = c.lower() if c == 'r': hero = Rogue() elif c == 'm': hero = Mage() elif c == 'b': hero = Barbarian() self.game = Game("rooms/startroom", hero) def play(self): '''(Game) -> NoneType The main game loop.''' exit = False while not exit: print(self) if self.game.game_over(): break c = input("Next: ") if c in ['q', 'x']: print("Thanks for playing!") exit = True elif c == 'w': # UP self.game.move_hero(-1, 0) elif c == 's': # DOWN self.game.move_hero(1, 0) elif c == 'a': # LEFT self.game.move_hero(0, -1) elif c == 'd': # RIGHT self.game.move_hero(0, 1) elif c == 'r': ## RESTART GAME self.initialize_game() else: pass def __str__(self): '''(GameScreen) -> NoneType Return a string representing the current room. Include the game's Hero string represetation and a status message from the last action taken.''' room = self.game.current_room s = "" if self.game.game_over(): #render a GAME OVER screen with text mostly centered #in the space of the room in which the character died. #top row s += "X" * (2 + room.cols) + "\n" #empty rows above GAME OVER for i in list(range(floor((room.rows - 2) / 2))): s += "X" + " " * room.cols + "X\n" # GAME OVER rows s += ("X" + " " * floor((room.cols - 4) / 2) + "GAME" + " " * ceil((room.cols - 4) / 2) + "X\n") s += ("X" + " " * floor((room.cols - 4) / 2) + "OVER" + " " * ceil((room.cols - 4) / 2) + "X\n") #empty rows below GAME OVER for i in list(range(ceil((room.rows - 2) / 2))): s += "X" + " " * room.cols + "X\n" #bottom row s += "X" * (2 + room.cols) + "\n" else: for i in range(room.rows): for j in room.grid[i]: if j is not None: if j.visible: s += j.symbol() else: #This is the symbol for 'not yet explored' : ? s += "?" s += "\n" #hero representation s += str(self.game.hero) #last status message s += room.status return s if __name__ == '__main__': gs = GameScreen() gs.initialize_game() gs.play() 

Cuando ejecuto este código, obtengo este error: TypeError: init () toma al menos 2 argumentos (1 dado) que tiene que ver con Rogue () u otras clases de héroe. Aquí está el hero.py.

 class Rogue(Tile): '''A class representing the hero venturing into the dungeon. Heroes have the following attributes: a name, a list of items, hit points, strength, gold, and a viewing radius. Heroes inherit the visible boolean from Tile.''' def __init__(self, rogue, bonuses=(0, 0, 0)): '''(Rogue, str, list) -> NoneType Create a new hero with name Rogue, an empty list of items and bonuses to hp, strength, gold and radius as specified in bonuses''' self.rogue = rogue self.items = [] self.hp = 10 + bonuses[0] self.strength = 2 + bonuses[1] self.radius = 2 + bonuses[2] Tile.__init__(self, True) def symbol(self): '''(Rogue) -> str Return the map representation symbol of Hero: O.''' #return "\u263b" return "O" def __str__(self): '''(Item) -> str Return the Hero's name.''' return "{}\nHP:{:2d} STR:{:2d} RAD:{:2d}\n".format( self.rogue, self.hp, self.strength, self.radius) def take(self, item): '''ADD SIGNATURE HERE Add item to hero's items and update their stats as a result.''' # IMPLEMENT TAKE METHOD HERE pass def fight(self, baddie): '''ADD SIGNATURE HERE -> str Fight baddie and return the outcome of the battle in string format.''' # Baddie strikes first # Until one opponent is dead # attacker deals damage equal to their strength # attacker and defender alternate if self.hp < 0: return "Killed by" return "Defeated" 

¿Qué estoy haciendo mal?

El problema

En GameScreen.initialize_game() , establece hero=Rogue() , pero el constructor de Rogue toma el rogue como un argumento. (Dicho de otra manera, el __init__ de Rogue requiere que se pase el rogue ). Es probable que tengas este mismo problema cuando configuras hero=Mage y hero=Barbarian .

La solución

Por suerte la solución es simple; puedes cambiar hero=Rogue() a hero=Rogue("MyRogueName") . Tal vez podría pedirle al usuario un nombre en initialize_game y luego usar ese nombre.

Notas sobre “al menos 2 argumentos (1 dado)”

Cuando ve errores como este, significa que ha llamado a una función o un método sin pasarle suficientes argumentos. ( __init__ es solo un método especial al que se llama cuando se inicializa un objeto). Por lo tanto, al depurar cosas como estas en el futuro, mire a dónde llama una función / método y dónde lo define, y asegúrese de que los dos tengan El mismo número de parámetros.

Una cosa que es un tanto difícil de este tipo de errores, es el self que se transmite.

 >>> class MyClass: ... def __init__(self): ... self.foo = 'foo' ... >>> myObj = MyClass() 

En ese ejemplo, uno podría pensar: “Raro, inicialicé myObj , así que se llamó MyClass.__init__ ; ¿por qué no tuve que pasar algo por mí self ?” La respuesta es que el self se pasa efectivamente cuando se usa la notación “object.method ()”. Esperemos que eso ayude a aclarar el error y explique cómo depurarlo en el futuro.

 Class Rogue: ... def __init__(self, rogue, bonuses=(0, 0, 0)): ... 

__init__ de tu clase Rogue necesita un rogue parámetro, pero lo estás creando como hero = Rogue() en initialize_game .

Necesitas pasarle algún parámetro apropiado como hero = Rogue('somename')