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?

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

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

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)
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.