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

2 Answers 2

76

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.

Sign up to request clarification or add additional context in comments.

3 Comments

makes sense, I thought they were bounded to the instance in both cases... thanks :)
Python has a complicated set of attribute lookup rules. 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.
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.
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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.