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'
defuz
  • 26,721
  • 10
  • 38
  • 60
Mantas Marcinkus
  • 603
  • 2
  • 6
  • 11
  • 11
    indent your code properly. – Ashwini Chaudhary Oct 17 '12 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. – jsbueno Oct 17 '12 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. – martineau Oct 17 '12 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 – jsbueno Oct 17 '12 at 16:48
  • @martineau: Just check the -I-won't-call-this-a-coincidence question from today: http://stackoverflow.com/questions/12939288/confusion-with-properties – jsbueno Oct 17 '12 at 19:30
  • @jsbueno: I would assume anyone starting to use poperties for the first time would have read about them in the documentation. The first line of it for the `property()` functions says: "Return a property attribute for _new-style classes_ (classes that derive from _object_)." Same for most other of the feature you mentioned. The OP in this case has a rep of 11, so given that and the nature of their problem, whether their class was new-style or not is of little relevance -- so IMHO you comment(s) are more of a distraction than anything else. – martineau Oct 17 '12 at 20:32

2 Answers2

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 = []
NullUserException
  • 83,810
  • 28
  • 209
  • 234
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 ")