Lorsque j'essaye de créer un objet 'BJ_player':

player = BJ_player(name, number_chips)

Je reçois:

TypeError: init () prend exactement 2 arguments positionnels (3 donnés).

J'ai utilisé la même méthodologie pour hériter de 'BJ_Hand' que pour hériter de 'Hand'.

Quelqu'un pourrait-il expliquer?

Cette première classe est située dans 'cardsmodule':

class Hand(object):
    """A hand of playing cards"""
    def __init__(self):
        self.cards = []

    def __str__(self):
        if self.cards:
            rep = ""
            for card in self.cards:
                rep += str(card) + "\t"
        else:
            rep = "<empty>"
        return rep
class BJ_hand(cardsmodule.Hand):
    """A BlackJack hand"""

    def __init__(self, name):
        super(BJ_hand, self).__init__()
        self.name = name

    def __str__(self):
        rep = self.name + "\t" + super(BJ_hand,self).__str__()
        if self.total:
            rep += "(" + str(self.total) + ")"
        return rep

class BJ_player(BJ_hand):
    """A BlackJack player"""
    def __init__(self, number_chips):
        super(BJ_player, self).__init__()
        #self.name = name
        self.number_chips = number_chips

    def __str__(self):
        rep = self.name + " has " + str(self.number_chips) + " chips.\n"
        rep += super(BJ_player, self).__init__()
0
Michael Johnson 7 août 2016 à 12:02

4 réponses

Meilleure réponse

Vous avez défini une méthode __init__ qui ne prend qu'un argument (plus self):

class BJ_player(BJ_hand):
    """A BlackJack player"""
    def __init__(self, number_chips):
        #              ^^^^^^^^^^^^

Il n'y a pas de paramètre pour name, mais vous essayez de le transmettre dans:

player = BJ_player(name, number_chips)
#                  ^^^^  ^^^^^^^^^^^^

Python ne regarde pas toutes les méthodes de base __init__ pour vous; il ne verra que BJ_player. Si vous vouliez passer une valeur name pour BJ_hand.__init__, BJ_player.__init__() doit accepter cela comme argument. Vous pouvez ensuite le transmettre via l'appel super().__init__():

class BJ_player(BJ_hand):
    """A BlackJack player"""
    def __init__(self, name, number_chips):
        super(BJ_player, self).__init__(name)

Notez comment le paramètre name de la méthode est désormais transmis dans la chaîne.

2
Martijn Pieters 7 août 2016 à 09:39

Cela ne donne aucune erreur sur py2.7 et py3.5:

class Hand(object):
    """A hand of playing cards"""
    def __init__(self):
        self.cards = []

    def __str__(self):
        if self.cards:
            rep = ""
            for card in self.cards:
                rep += str(card) + "\t"
        else:
            rep = "<empty>"
        return rep

class BJ_hand(Hand):
    """A BlackJack hand"""

    def __init__(self, name):
        super(BJ_hand, self).__init__()
        self.name = name


    def __str__(self):
        rep = self.name + "\t" + super(BJ_hand,self).__str__()
        if self.total:
            rep += "(" + str(self.total) + ")"
        return rep

class BJ_player(BJ_hand):
    """A BlackJack player"""
    def __init__(self, number_chips):
        super(BJ_player, self).__init__('aName')
        self.number_chips = number_chips

    def __str__(self):
        rep = self.name + " has " + str(self.number_chips) + " chips.\n"
        rep += super(BJ_player, self).__init__()

b = BJ_player (3)
1
Jacques de Hooge 7 août 2016 à 09:37

La classe BJ_player a un problème. Modifié la classe en ceci:

class BJ_player(BJ_hand):
    """A BlackJack player"""
    def __init__(self, name, number_chips):
        super(BJ_player, self).__init__(name)
        self.name = name
        self.number_chips = number_chips

    def __str__(self):
        rep = self.name + " has " + str(self.number_chips) + " chips.\n"
        rep += super(BJ_player, self).__init__(self.name)

J'ai essayé ça et ça marche

1
Evans Murithi 7 août 2016 à 09:39

Alors que les autres réponses ont (la plupart du temps) correctement diagnostiqué le problème spécifique que vous décrivez (n'acceptez pas name dans BJ_player.__init__ et le transmettez dans l'appel super), je pense qu'il y a une conception plus large problème qui peut vous poser d'autres problèmes lors de l'utilisation de vos classes.

Plus précisément, la relation entre un joueur et les cartes en main n'est pas bien représentée par l'héritage. L'héritage est souvent décrit comme une relation «IS-A». Par exemple, il serait logique de définir une classe Dog qui hérite d'une classe parent Animal, car chaque chien est un animal.

Ce n'est pas le cas des joueurs et des mains. Un joueur de blackjack n'est pas un certain type de main de cartes. Chaque joueur a une main de cartes. Une relation "HAS-A" entre les objets est mieux mise en œuvre avec la composition. En d'autres termes, une instance BJ_player doit avoir une instance Hand en tant que variable d'instance. Cela pourrait libérer votre conception d'autres manières. Par exemple, lorsqu'il n'est pas occupé dans un casino, un joueur peut jouer plusieurs mains à la fois à la même table. Ce serait impossible à représenter avec héritage, mais il serait assez facile de changer l'instance unique Hand en cours d'enregistrement dans une variable d'instance sur l'instance Player en une liste d'un ou plusieurs {{ X4}} instances.

Je suggère également que l'attribut name sur lequel vous stockez BJ_hand est vraiment plus approprié en tant qu'attribut sur le lecteur. Il peut toujours être judicieux d'avoir une classe BJ_hand, qui pourrait traiter des choses comme le comptage de la valeur des cartes distribuées (et si vous avez déjà éclaté ou non), mais vous devrez peut-être réfléchir un peu les attributs ont du sens à stocker sur la main et qui sont plus appropriés ailleurs.

1
Blckknght 7 août 2016 à 09:49