NameError: o nome 'self' não está definido

144

Por que essa estrutura

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

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

dá um erro NameError: name 'self' is not defined?

chriss
fonte

Respostas:

159

Os valores padrão do argumento são avaliados no tempo de definição da função, mas selfé um argumento disponível apenas no momento da chamada da função. Portanto, os argumentos da lista de argumentos não podem se referir.

É um padrão comum usar como padrão um argumento Nonee adicionar um teste para isso no código:

def p(self, b=None):
    if b is None:
        b = self.a
    print b
intgr
fonte
4
Embora eu ache que o exposto acima não seja muito bonito (eu venho de ruby, onde as coisas funcionam bem), o exposto realmente funciona como uma solução alternativa. Ainda é estranho que o python tenha optado por se tornar indisponível em uma lista de parâmetros.
shevy
2
@shevy: "self" não tem significado especial em python, é apenas o nome escolhido convencionalmente para o primeiro argumento. Você também pode substituir "self" por "me" ou "x".
Max
Não existe melhor maneira de fazer isso? Se temos uma função que recebe uma dúzia de argumentos padrão que devem se referir a si, precisamos mesmo de uma dúzia de instruções if? Isso é terrivelmente estranho.
Richard J. Barbalace
16

Nos casos em que você também deseja ter a opção de definir 'b' como Nenhum:

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

Se você chegou aqui pelo google, verifique se você se deu como o primeiro parâmetro para uma função de classe. Especialmente se você tentar fazer referência a valores para esse objeto dentro da função.

def foo():
    print(self.bar)

> NameError: o nome 'self' não está definido

def foo(self):
    print(self.bar)
Erich
fonte