NameError: ім'я "self" не визначено


145

Чому така структура

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

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

дає помилку NameError: name 'self' is not defined?

Відповіді:


159

Значення аргументів за замовчуванням оцінюються під час визначення функції, але selfце аргумент, доступний лише під час виклику функції. Таким чином, аргументи у списку аргументів не можуть посилатися один на одного.

Це загальний шаблон для аргументу за замовчуванням Noneта додавання тесту для цього в коді:

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

4
Хоча я вважаю, що вищесказане не дуже симпатичне (я родом з рубіну, де все просто працює нормально), сказане насправді працює як спосіб вирішення. Досі незручно, що python вирішив зробити себе недоступним у списку параметрів.
шеві

2
@shevy: "Я" не має особливого значення в python, це лише ім'я, умовно вибране для першого аргументу. Ви також можете замінити "Я" на "мене" або "х".
Макс

Чи немає кращого способу це зробити? Якщо у нас є функція, яка бере десяток аргументів за замовчуванням, які повинні посилатися на себе, чи нам справді потрібен десяток, якщо заяви? Це страшенно незручно.
Річард Дж. Барбалас

16

У випадках, коли ви також хочете мати можливість встановити "b" значення None:

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

6

Якщо ви приїхали сюди через google, переконайтеся, що ви переконалися, що ви дали себе як перший параметр функції класу. Особливо, якщо ви намагаєтеся посилати значення для цього об'єкта всередині функції.

def foo():
    print(self.bar)

> NameError: ім'я "self" не визначено

def foo(self):
    print(self.bar)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.