AttributeError: объект 'Class' не имеет атрибута 'a'

Здесь у меня есть атрибут 'a', который определен в методе первого класса и должен быть изменен во втором. При вызове их по порядку появляется следующее сообщение:

AttributeError: объект 'Class' не имеет атрибута 'a'

Единственный способ, который я нашел, - определить 'a' снова во втором методе, но в реальном коде он имеет длинное наследование и приложение будет запущено. Почему это не работает? Разве это не self.a равно Class.a?

class Class(object):
    def method_1(self):
        self.a = 1
    def method_2(self):
        self.a += 1

Class().method_1()
Class().method_2()

Ответ 1

Короткий ответ, нет. Проблема с вашим кодом заключается в том, что каждый раз, когда вы создаете новый экземпляр.

Изменить: Как упоминает abarnert ниже, между Class.a и ca существует большая разница. Атрибуты экземпляра (второй случай) относятся к каждому конкретному объекту, тогда как атрибуты класса относятся к классу. Посмотрите на комментарий abarnert ниже или обсуждение здесь для получения дополнительной информации.

Ваш код эквивалентен

c1 = Class()
c1.method_1()  # defines c1.a (an instance attribute)
c2 = Class()
c2.method_2()  # c2.a undefined (the c2 instance doesn't have the attribute)

Вы, вероятно, захотите сделать что-то вроде

c = Class()
c.method_1()  # c.a = 1
c.method_2()  # c.a = 2
print "c.a is %d" % c.a  # prints "c.a is 2"

Или, возможно, даже лучше было бы инициализировать c с a атрибуте

class Class:
    def __init__(self):
        self.a = 1  # all instances will have their own a attribute

Ответ 2

Недавно созданный экземпляр Class не имеет атрибута a когда вы делаете instance_of_class.method_2() без вызова method_1, как в вашем примере.

Рассмотрим эту слегка измененную версию вашего кода:

class CreateNewClassInstance(object):
    def create_a(self):
        self.a = 1
    def add_one_to_a(self):
        self.a += 1

CreateNewClassInstance().create_a()
CreateNewClassInstance().add_one_to_a()

Каждый раз, когда вы вызываете Class() (или CreateNewClassInstance()), вы создаете новый объект со своим собственным атрибутом a. Пока вы не инициализируете a, у вас нет атрибута с этим именем.

В большинстве случаев это не проблема, однако += будет пытаться загрузить self.a перед добавлением к ней - вот что вызывает ваш AttributeError в этом случае.