Python: экземпляр не имеет атрибута

У меня проблема со списком внутри класса в python. Вот мой код:

class Residues:
    def setdata(self, name):
        self.name = name
        self.atoms = list()

a = atom
C = Residues()
C.atoms.append(a)

Что-то вроде этого. Я получаю сообщение об ошибке:

AttributeError: Residues instance has no attribute 'atoms'

person Mantas Marcinkus    schedule 17.10.2012    source источник
comment
сделайте отступ в коде правильно.   -  person Ashwini Chaudhary    schedule 17.10.2012
comment
С другой стороны, если вы используете Python 2.x, вы должны наследовать свой класс от объекта или в будущем столкнуться с очень трудным для понимания неправильным поведением.   -  person jsbueno    schedule 17.10.2012
comment
@jsbueno: я сильно в этом сомневаюсь. Классы в старом стиле существуют уже давно, как следует из названия, и каким-то образом людям удавалось прекрасно разбираться в их плохом поведении.   -  person martineau    schedule 17.10.2012
comment
@martineau: Просто неправильно их больше использовать: дескрипторы не работают, mro (следовательно, вызовы super) не работают, среди прочего. Нет причин не использовать новые классы стиля, если ваша программа не должна работать в Python 2.1.   -  person jsbueno    schedule 17.10.2012
comment
@martineau: Просто проверьте сегодняшний вопрос «Я не буду называть это совпадением»: stackoverflow.com/questions/12939288/confusion-with-properties   -  person jsbueno    schedule 17.10.2012
comment
@jsbueno: я полагаю, что любой, кто впервые начинает использовать свойства, прочитал бы о них в документации. В первой строке для функций property() говорится: вернуть атрибут свойства для классов нового стиля (классов, производных от object). То же самое для большинства других функций, которые вы упомянули. ОП в этом случае имеет репутацию 11, поэтому, учитывая это и характер их проблемы, независимо от того, был ли их класс в новом стиле или нет, это не имеет большого значения - так что ИМХО ваши комментарии больше отвлекают, чем что-либо еще еще.   -  person martineau    schedule 18.10.2012


Ответы (1)


В вашем классе нет __init__(), поэтому к моменту его создания атрибут atoms отсутствует. Вам нужно будет сделать C.setdata('something'), чтобы C.atoms стало доступным.

>>> C = Residues()
>>> C.atoms.append('thing')

Traceback (most recent call last):
  File "<pyshell#84>", line 1, in <module>
    B.atoms.append('thing')
AttributeError: Residues instance has no attribute 'atoms'

>>> C.setdata('something')
>>> C.atoms.append('thing')   # now it works
>>> 

В отличие от таких языков, как Java, где вы знаете во время компиляции, какие атрибуты/переменные-члены будут у объекта, в Python вы можете динамически добавлять атрибуты во время выполнения. Это также означает, что экземпляры одного и того же класса могут иметь разные атрибуты.

Чтобы гарантировать, что у вас всегда будет (если вы не возитесь с ним по линии, тогда это ваша собственная ошибка) список atoms, вы можете добавить конструктор:

def __init__(self):
    self.atoms = []
person NullUserException    schedule 17.10.2012
comment
+1. OP также может добавить метод def __init__(self): self.residues = [], если он хочет, чтобы atoms был установлен еще до вызова setdata - person David Robinson; 17.10.2012
comment
Я назвал свою функцию __init()_, пропустив последнюю _ ... спасибо - person Goot; 12.02.2016