59 votes

Erreur Python intéressante "prend exactement 1 argument (2 donnés)".

Pour l'erreur :

TypeError: takes exactly 1 argument (2 given)

Avec la méthode de classe suivante :

def extractAll(tag):
   ...

et de l'appeler :

e.extractAll("th")

L'erreur semble très étrange lorsque je lui donne 1 argument, la méthode ne devrait prendre qu'un seul argument, mais elle dit que je ne lui donne pas 1 argument.... Je sais que le problème peut être résolu en ajoutant self dans le prototype de la méthode, mais je voulais connaître la raison de cette erreur.

Est-ce que je l'obtiens parce que l'acte de l'appeler via e. extractAll("th") passe aussi en self comme un argument ? Et si oui, en supprimant le self dans l'appel, serais-je en train d'en faire une sorte de méthode de classe qui peut être appelée comme Extractor.extractAll("th") ?

80voto

Sven Marnach Points 133943

L'appel

e.extractAll("th")

pour une méthode régulière extractAll() est en effet équivalent à

Extractor.extractAll(e, "th")

Ces deux appels sont traités de la même manière à tous égards, y compris les messages d'erreur que vous recevez.

Si vous n'avez pas besoin de passer l'instance à une méthode, vous peut utiliser un staticmethod :

@staticmethod
def extractAll(tag):
    ...

qui peut être appelé comme e.extractAll("th") . Mais je me demande pourquoi il s'agit d'une méthode sur une classe si vous n'avez pas besoin d'accéder à une instance.

28voto

Martin Points 101

Si une méthode non statique est membre d'une classe, vous devez la définir comme telle :

def Method(self, atributes..)

Donc, je suppose que votre 'e' est une instance d'une classe avec une méthode implémentée qui essaie de s'exécuter et qui a trop d'arguments.

9voto

Daniel Roseman Points 199743

Est-ce que je l'obtiens parce que l'acte de l'appeler via e.extractAll("th") passe aussi dans self comme un argument ?

Oui, c'est exactement ça. Si vous voulez, le premier paramètre est le nom de l'objet, e avec lequel vous l'appelez.

Et si c'est le cas, en supprimant le self dans l'appel, est-ce que j'en ferais une sorte de méthode de classe qui pourrait être appelée comme Extractor.extractAll("th") ?

Pas tout à fait. Une classmethod a besoin du @classmethod et qui accepte le décorateur classe en tant que premier paramètre (généralement référencé en tant que cls ). Le seul type de méthode qui ne reçoit aucun paramètre automatique est connu sous le nom de staticmethod, et qui a également besoin d'un décorateur (sans surprise, il s'agit de @staticmethod ). Une classmethod est utilisée lorsqu'il s'agit d'une opération qui doit se référer à la classe elle-même : peut-être l'instanciation d'objets de la classe ; une staticmethod est utilisée lorsque le code appartient logiquement à la classe, mais ne nécessite aucun accès à la classe ou à l'instance.

Mais oui, les staticmethods et les classmethods peuvent être appelés en référençant le nom de la classe comme vous le décrivez : Extractor.extractAll("th") .

4voto

payne Points 5933

Oui, lorsque vous invoquez e.extractAll(foo) Python transforme cela en extractAll(e, foo) .

En http://docs.python.org/tutorial/classes.html

la particularité des méthodes est que l'objet est passé comme le premier argument de la fonction. Dans notre Dans notre exemple, l'appel x.f() est exactement équivalent à MyClass.f(x). Sur général, l'appel d'une méthode avec une liste de n arguments est équivalent à appeler la fonction correspondante avec une liste d'arguments qui est créée en insérant l'objet de la méthode avant le premier argument .

C'est nous qui soulignons.

1voto

Rui Lima Points 1299

Essayez d'utiliser :

def extractAll(self,tag):

attention à soi

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X