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


145

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 ?

Réponses:


159

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

C'est un modèle courant pour définir par défaut un argument Noneet ajouter un test pour cela dans le code:

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

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

2
@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».
Max

N'y a-t-il pas de meilleure façon de faire cela? 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.
Richard J. Barbalace le

16

Pour les cas où vous souhaitez également avoir la possibilité de définir «b» sur Aucun:

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

6

Si vous êtes arrivé ici via google, assurez-vous de vérifier que vous vous êtes donné comme premier paramètre à une fonction de classe. Surtout si vous essayez de référencer des valeurs pour cet objet dans la fonction.

def foo():
    print(self.bar)

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

def foo(self):
    print(self.bar)
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.