57

I was wondering what was the best practice for initializing object attributes in Python, in the body of the class or inside the __init__ function?

i.e.

class A(object):
    foo = None

vs

class A(object):
   def __init__(self):
       self.foo = None
fortran
  • 74,053
  • 25
  • 135
  • 175

2 Answers2

77

If you want the attribute to be shared by all instances of the class, use a class attribute:

class A(object):
    foo = None

This causes ('foo',None) to be a (key,value) pair in A.__dict__.

If you want the attribute to be customizable on a per-instance basis, use an instance attribute:

class A(object):
   def __init__(self):
       self.foo = None

This causes ('foo',None) to be a (key,value) pair in a.__dict__ where a=A() is an instance of A.

unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
  • 1
    makes sense, I thought they were bounded to the instance in both cases... thanks :) – fortran Oct 18 '11 at 15:06
  • 9
    Python has a complicated set of [attribute lookup rules](http://www.cafepy.com/article/python_attributes_and_methods/python_attributes_and_methods.html). Without getting into descriptors, for this case it suffices to know `a.__dict__` is searched for the `foo` key first, and if it is not found there, then `A.__dict__` is searched. This is why you can use `a.foo` even if `foo` is a class attribute. – unutbu Oct 18 '11 at 15:19
  • 5
    Also noteworthy is that for class attributes, if you were to do `a.foo = whatever`, you'd actually end up creating a new instance attribute (which hides the class attribute). `A.foo` would be unchanged. It's kinda a gotcha, since you can access the value of `A.foo` with `a.foo`, but assigning to that would create a new instance attribute. – Kat Apr 13 '17 at 22:31
4

Attributes defined in the class definition are considered class variables (like static variables in Java), while those set in the initializer are instance attributes (note the difference between self.something = 1 and something = 1). See this question for more details, and this one for even more. There is not a lot of practical difference between these two cases, as the class-level definition gives the attribute a default value, but if you want to use some kind of logic to set an attribute before using an object instance you should do it in the __init__() method.

Community
  • 1
  • 1
andronikus
  • 4,125
  • 2
  • 29
  • 46