NameError: Der Name 'self' ist nicht definiert


144

Warum so eine Struktur

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

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

gibt einen Fehler NameError: name 'self' is not defined?

Antworten:


159

Standardargumentwerte werden zum Zeitpunkt der Funktionsdefinition ausgewertet, sind jedoch selfnur zum Zeitpunkt des Funktionsaufrufs verfügbar. Daher können sich die Argumente in der Argumentliste nicht gegenseitig referenzieren.

Es ist ein gängiges Muster, ein Argument als Standard festzulegen Noneund einen Test dafür im Code hinzuzufügen:

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

4
Obwohl ich denke, dass das Obige nicht sehr hübsch ist (ich komme aus Ruby, wo die Dinge einfach gut funktionieren), funktioniert das Obige tatsächlich als Problemumgehung. Es ist immer noch umständlich, dass Python sich dafür entschieden hat, sich in einer Parameterliste nicht verfügbar zu machen.
Shevy

2
@shevy: "self" hat in Python keine besondere Bedeutung, es ist nur der Name, der herkömmlicherweise für das erste Argument gewählt wird. Sie können auch "self" durch "me" oder "x" ersetzen.
Max

Gibt es keinen besseren Weg, dies zu tun? Wenn wir eine Funktion haben, die ein Dutzend Standardargumente akzeptiert, die auf self verweisen sollen, brauchen wir dann wirklich ein Dutzend if-Anweisungen? Das ist furchtbar umständlich.
Richard J. Barbalace

16

Für Fälle, in denen Sie auch die Option haben möchten, 'b' auf Keine zu setzen:

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

6

Wenn Sie über Google hier angekommen sind, überprüfen Sie bitte, ob Sie sich selbst als ersten Parameter für eine Klassenfunktion angegeben haben. Insbesondere, wenn Sie versuchen, Werte für dieses Objekt innerhalb der Funktion zu referenzieren.

def foo():
    print(self.bar)

> NameError: Der Name 'self' ist nicht definiert

def foo(self):
    print(self.bar)
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.