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?

Chriss
источник

Ответы:

159

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

Это обычный шаблон для установки аргумента по умолчанию Noneи добавления теста для этого в коде:

def p(self, b=None):
    if b is None:
        b = self.a
    print b
время интегрирования
источник
4
Хотя я думаю, что вышеупомянутое не очень красиво (я пришел из рубина, где все просто отлично работает), вышеописанное на самом деле работает как обходной путь. Все еще неудобно, что python решил сделать себя недоступным в списке параметров.
shevy
2
@shevy: «self» не имеет особого значения в python, это просто имя, традиционно выбранное для первого аргумента. Вы также можете заменить «я» на «я» или «х».
Макс
Нет лучшего способа сделать это? Если у нас есть функция, которая принимает дюжину аргументов по умолчанию, которые должны ссылаться на себя, нужна ли нам дюжина операторов if? Это ужасно неловко.
Ричард Дж. Барбалас
16

Для случаев, когда вы также хотите, чтобы параметр 'b' был установлен в None:

def p(self, **kwargs):
    b = kwargs.get('b', self.a)
    print b
Андрей
источник
6

Если вы пришли сюда через Google, убедитесь, что вы указали self в качестве первого параметра функции класса. Особенно, если вы пытаетесь ссылаться на значения для этого объекта внутри функции.

def foo():
    print(self.bar)

> NameError: имя 'self' не определено

def foo(self):
    print(self.bar)
Erich
источник