NameError: name 'self' nie jest zdefiniowana

144

Dlaczego taka konstrukcja

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

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

daje błąd NameError: name 'self' is not defined?

chriss
źródło

Odpowiedzi:

159

Domyślne wartości argumentów są oceniane w czasie definiowania funkcji, ale selfsą argumentami dostępnymi tylko w czasie wywołania funkcji. Dlatego argumenty na liście argumentów nie mogą się odnosić.

Jest to typowy wzorzec do domyślnego argumentu Nonei dodawania testu w kodzie:

def p(self, b=None):
    if b is None:
        b = self.a
    print b
intgr
źródło
4
Chociaż uważam, że powyższe nie jest zbyt ładne (pochodzę z ruby, gdzie wszystko działa dobrze), powyższe działa jako obejście. To wciąż niezręczne, że Python zdecydował się uczynić self niedostępnym na liście parametrów.
shevy
2
@shevy: "self" nie ma specjalnego znaczenia w Pythonie, to tylko nazwa tradycyjnie wybrana jako pierwszy argument. Możesz również zamienić „ja” na „ja” lub „x”.
Max
Czy nie ma lepszego sposobu, aby to zrobić? Jeśli mamy funkcję, która przyjmuje tuzin domyślnych argumentów, które powinny odwoływać się do siebie, czy naprawdę potrzebujemy kilkunastu instrukcji if? To strasznie niezręczne.
Richard J. Barbalace
16

W przypadkach, w których chcesz mieć również opcję ustawienia „b” na Brak:

def p(self, **kwargs):
    b = kwargs.get('b', self.a)
    print b
Andrzej
źródło
6

Jeśli dotarłeś tutaj przez Google, upewnij się, że podałeś self jako pierwszy parametr funkcji klasowej. Zwłaszcza jeśli spróbujesz odwołać się do wartości dla tego obiektu wewnątrz funkcji.

def foo():
    print(self.bar)

> NameError: nazwa „self” nie jest zdefiniowana

def foo(self):
    print(self.bar)
Erich
źródło