183 votes

NameError : le nom "self" n'est pas défini

Pourquoi une telle structure ?

class A:
    def __init__(self, a):
        self.a = a

    def p(self, b=self.a):
        print b

donne une erreur NameError: name 'self' is not defined ?

202voto

intgr Points 9041

Les valeurs par défaut des arguments sont évaluées au moment de la définition de la fonction, mais les valeurs de l'argument self est un argument disponible uniquement au moment de l'appel de la fonction. Les arguments de la liste d'arguments ne peuvent donc pas se référer les uns aux autres.

Il est courant d'ajouter par défaut un argument à l'expression None et ajouter un test pour cela dans le code :

def p(self, b=None):
    if b is None:
        b = self.a
    print b

Mise à jour 2022 : Les développeurs Python sont désormais prise en compte des valeurs par défaut des arguments tardifs pour les futures versions de Python.

7 votes

Bien que je pense que ce qui précède n'est pas très joli (je viens de ruby où les choses fonctionnent bien), ce qui précède fonctionne en fait comme une solution de contournement. Il est tout de même gênant que python ait choisi de rendre self indisponible dans une liste de paramètres.

4 votes

@shevy : "self" n'a pas de signification particulière en python, c'est juste le nom. conventionnellement choisi pour le premier argument. Vous pouvez également remplacer "self" par "me" ou "x".

2 votes

N'y a-t-il pas de meilleure façon de procéder ? Si nous avons une fonction qui prend une douzaine d'arguments par défaut qui devraient référencer self, avons-nous vraiment besoin d'une douzaine d'instructions if ? C'est terriblement gênant.

20voto

Andrew Points 91

Pour les cas où vous souhaitez également avoir la possibilité de régler "b" sur Aucun :

def p(self, **kwargs):
    b = kwargs.get('b', self.a)
    print b

16voto

Erich Points 524

A self NameError peut également se produire si vous ne définissez pas self dans la signature d'une méthode. Cette erreur apparaît généralement sous la forme suivante TypeError Il n'y a pas d'accord entre les arguments attendus et les arguments donnés[1]. Cependant, si vous acceptez un nombre variable d'arguments, self sera arg[0] et la variable self sera indéfinie.

Un exemple minimal.

class Obj:
    def foo(*args):
        print(self.bar)

>NameError : le nom 'self' n'est pas défini

Correction :

class Obj:
    def baz(self, *args):
        print(self.bar)

[1] http://neopythonic.blogspot.com/2008/10/why-explicit-self-has-to-stay.html

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