Si j'ai un cours ...
class MyClass:
def method(arg):
print(arg)
... que j'utilise pour créer un objet ...
my_object = MyClass()
... sur lequel j'appelle method("foo")
comme si ...
>>> my_object.method("foo")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: method() takes exactly 1 positional argument (2 given)
... pourquoi Python me dit-il que je lui ai donné deux arguments, alors que je n'en ai donné qu'un?
En Python, ceci:
my_object.method("foo")
... is sucre syntaxique , que l'interprète traduit en coulisse:
MyClass.method(my_object, "foo")
... qui, comme vous pouvez le constater, a bien deux arguments - c'est simplement que le premier est implicite, du point de vue de l'appelant.
En effet, la plupart des méthodes fonctionnent avec l'objet sur lequel elles ont été appelées. Il doit donc exister un moyen de faire référence à cet objet dans la méthode. Par convention, ce premier argument s'appelle self
dans la définition de la méthode:
class MyNewClass:
def method(self, arg):
print(self)
print(arg)
Si vous appelez method("foo")
sur une instance de MyNewClass
, cela fonctionne comme prévu:
>>> my_new_object = MyNewClass()
>>> my_new_object.method("foo")
<__main__.MyNewClass object at 0x29045d0>
foo
De temps en temps (mais pas souvent), vous ne vous souciez pas de l'objet auquel votre méthode est liée, et dans ce cas, vous pouvez - décorer la méthode avec le --- staticmethod()
fonction pour le dire:
class MyOtherClass:
@staticmethod
def method(arg):
print(arg)
... Dans ce cas, vous n'avez pas besoin d'ajouter un argument self
à la définition de la méthode, et cela fonctionne toujours:
>>> my_other_object = MyOtherClass()
>>> my_other_object.method("foo")
foo
Autre chose à considérer lorsque ce type d'erreur est rencontré:
Je courais dans ce message d'erreur et trouvé ce post utile. Il se trouve que dans mon cas, j'avais remplacé un init () où il y avait un héritage d'objet.
L'exemple hérité est plutôt long, je vais donc passer à un exemple plus simple qui n'utilise pas l'héritage:
class MyBadInitClass:
def ___init__(self, name):
self.name = name
def name_foo(self, arg):
print(self)
print(arg)
print("My name is", self.name)
class MyNewClass:
def new_foo(self, arg):
print(self)
print(arg)
my_new_object = MyNewClass()
my_new_object.new_foo("NewFoo")
my_bad_init_object = MyBadInitClass(name="Test Name")
my_bad_init_object.name_foo("name foo")
Le résultat est:
<__main__.MyNewClass object at 0x033C48D0>
NewFoo
Traceback (most recent call last):
File "C:/Users/Orange/PycharmProjects/Chapter9/bad_init_example.py", line 41, in <module>
my_bad_init_object = MyBadInitClass(name="Test Name")
TypeError: object() takes no parameters
PyCharm n'a pas attrapé cette faute de frappe. Notepad ++ non plus (d'autres éditeurs/IDE pourraient).
Certes, il s'agit d'un "ne prend aucun paramètre" TypeError, il n'est pas très différent de "got two" quand on en attend un, en termes d'initialisation d'objet en Python.
Aborder le sujet: Un initialiseur de surcharge sera utilisé si la syntaxe est correcte, mais sinon, il sera ignoré et la fonction intégrée utilisée à la place. L'objet n'attendra pas/ne gérera pas cela et l'erreur sera renvoyée.
Dans le cas de l'erreur sytax: le correctif est simple, il suffit de modifier l'instruction d'init personnalisée:
def __init__(self, name):
self.name = name
Cela se produit lorsque vous ne spécifiez pas le nombre de paramètres recherchés par la __init__()
ou toute autre méthode.
Par exemple:
class Dog:
def __init__(self):
print("IN INIT METHOD")
def __unicode__(self,):
print("IN UNICODE METHOD")
def __str__(self):
print("IN STR METHOD")
obj=Dog("JIMMY",1,2,3,"WOOF")
Lorsque vous exécutez le programme ci-dessus, cela vous donne une erreur comme celle-ci:
TypeError: __init __ () prend 1 argument de position mais 6 ont été donnés
Comment pouvons-nous nous débarrasser de cette chose?
Il suffit de passer les paramètres, quelle méthode __init__()
cherche
class Dog:
def __init__(self, dogname, dob_d, dob_m, dob_y, dogSpeakText):
self.name_of_dog = dogname
self.date_of_birth = dob_d
self.month_of_birth = dob_m
self.year_of_birth = dob_y
self.sound_it_make = dogSpeakText
def __unicode__(self, ):
print("IN UNICODE METHOD")
def __str__(self):
print("IN STR METHOD")
obj = Dog("JIMMY", 1, 2, 3, "WOOF")
print(id(obj))
Nouveau venu dans Python, je rencontrais ce problème lorsque j'utilisais la fonctionnalité **
de Python de manière erronée. Essayer d'appeler cette définition quelque part:
def create_properties_frame(self, parent, **kwargs):
utiliser un appel sans étoile double était à l'origine du problème:
self.create_properties_frame(frame, kw_gsp)
TypeError: create_properties_frame () prend 2 arguments de position mais 3 ont été donnés
La solution consiste à ajouter ** à l'argument:
self.create_properties_frame(frame, **kw_gsp)