The advantage of defining it in __init__() is that you know that'll be called before any other method is, so you avoid the risk of trying to access it before it's been created.
For instance, compare this code which creates the member variable in __init__():
#!/usr/bin/env python
class human(object):
def __init__(self):
self.name = '<unnamed baby>'
def nameBaby(self, name):
self.name = name
def getName(self):
return self.name
kid = human()
print kid.getName()
kid.nameBaby('Bruce')
print kid.getName()
outputting:
paul@thoth:~/src/sandbox$ ./baby1.py
<unnamed baby>
Bruce
paul@thoth:~/src/sandbox$
with this code, which does not:
#!/usr/bin/env python
class human(object):
def __init__(self):
pass
def nameBaby(self, name):
self.name = name
def getName(self):
return self.name
kid = human()
print kid.getName()
kid.nameBaby('Bruce')
print kid.getName()
outputting:
paul@thoth:~/src/sandbox$ ./baby2.py
Traceback (most recent call last):
File "./baby2.py", line 14, in <module>
print kid.getName()
File "./baby2.py", line 11, in getName
return self.name
AttributeError: 'human' object has no attribute 'name'
paul@thoth:~/src/sandbox$
You cannot usually control in which order a user might call your class methods and, in general, you shouldn't require your classes to depend on any such order. In circumstances such as those shown above, by creating your member variable in __init__(), your code is robust enough to function correctly regardless of which order the user calls methods in (although it doesn't guarantee you'll actually get anything particularly meaningful, of course).