23

I have a problem with list within a class in python. Here's my code :

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

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

Something like this. I get an error saying:

AttributeError: Residues instance has no attribute 'atoms'
6
  • 11
    indent your code properly. Commented Oct 17, 2012 at 16:27
  • 1
    On a side note, if yyou are using Python 2.x, you should inherit your class from "object" or be subject to really hard to figure out misbehaviors in the future. Commented Oct 17, 2012 at 16:32
  • 1
    @jsbueno: I strongly doubt that. Old-style class have been around for a long time, as the name implies, and somehow people have managed to figure out their "misbehaviors" just fine. Commented Oct 17, 2012 at 16:36
  • @martineau: I tsimply is not correct to use them anymore: descriptors don't work, mro (therefore calls to "super") don't work, among other things. There is no motive not to use new style classes, unless yor program needs to run in Python 2.1 Commented Oct 17, 2012 at 16:48
  • @martineau: Just check the -I-won't-call-this-a-coincidence question from today: stackoverflow.com/questions/12939288/confusion-with-properties Commented Oct 17, 2012 at 19:30

2 Answers 2

35

Your class doesn't have a __init__(), so by the time it's instantiated, the attribute atoms is not present. You'd have to do C.setdata('something') so C.atoms becomes available.

>>> 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
>>> 

Unlike in languages like Java, where you know at compile time what attributes/member variables an object will have, in Python you can dynamically add attributes at runtime. This also implies instances of the same class can have different attributes.

To ensure you'll always have (unless you mess with it down the line, then it's your own fault) an atoms list you could add a constructor:

def __init__(self):
    self.atoms = []
Sign up to request clarification or add additional context in comments.

2 Comments

+1. OP can also add the method def __init__(self): self.residues = [] if he wants atoms to be set even before setdata is called
I named my function __init()_ missing the last _ ... thank you
1

the error means the class Residues doesn't have a function call atoms. The solution could be as follows:

class Residues:
    def setdata(self,  atoms, name=None):
        self.name = name
        self.atoms =[]

C = Residues()
C.setdata(atoms= " a ")

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.