11

So I understand how to use init when defining a class in Python. However, I am confused as to what to put inside the init function, or if I should use it at all. For example:

Here I make the user define concept when the class is instantiated:

class Fruit(object):
 def __init__(self, concept):
 self.concept = concept

But I could also do this, and the user can just change the concept attribute themselves:

class Fruit(object):
 def __init__(self):
 self.concept = "I am a fruit"

Or I could just abandon the init function altogether:

class Fruit(object):
 concept = "I am a fruit"

In each of these examples, I can change the concept attribute as such

test = Fruit()
test.concept = 'Whatever I want'

So I'm not sure why I use the init function in the first place. It seems to only be convenient for defining all the attributes up front.

Moreover, how do I know what to put inside an init function and what to just define outside of the init?

asked Jan 28, 2017 at 17:29
5
  • 4
    The line concept = "I am a fruit" defines a class variable, not an instance variable. Commented Jan 28, 2017 at 17:32
  • test = Fruit('Whatever I want', "other", "Another") looks better then test = Fruit() ; test.concept = 'Whatever I want' ; test.concept_2 = "other" ; test.concept_3 = "Another" Commented Jan 28, 2017 at 17:34
  • Start off putting everything in __init__ till you come accross a need to to do something different. Commented Jan 28, 2017 at 17:36
  • 1
    __init__ should initialize an object, so that it is in a useful state. Commented Jan 28, 2017 at 17:37
  • @furas So it's more stylistic/user friendly than it is functional? Commented Jan 28, 2017 at 17:40

2 Answers 2

8
class Fruit(object):
 def __init__(self, concept):
 self.concept = concept

is the best approach because it allows you, as the maintainer of the class, flexibility in changing the inner workings. In addition, you may have data inside the class that should not be accessed by the client (in Python, it's not entirely possible to protect data, but there are some conventions that exist).

For example:

class Fruit(object):
 def __init__(self, concept):
 self.concept = concept
 self._super_secret_key = get_secret_key(concept)

You might not want _super_secret_key to be accessible by a client (again, it still is) but by prefixing the instance variable with _, you are conveying that it should be private.

In addition, the purpose of __init__ is to initialize the instance, so any initialization (such as setting variables) should be done there. You may want to read over Why do we use __init__ in python classes?.


class Fruit(object):
 def __init__(self):
 self.concept = "I am a fruit"

In each of these examples, I can change the concept attribute as such

test = Fruit()
test.concept = 'Whatever I want'

That type of code becomes messy very quickly. What if a year from now, you change the variable name of concept, or abandon that usage altogether? All of the clients of that class (i.e. any time you use the Fruit class) are now non-functional.


class Fruit(object):
 concept = "I am a fruit"

This serves an entirely different purpose, as concept is now a class variable, not an instance variable. As such, it is shared by all instances and can be modified in similar fashion:

In [1]: class Fruit(object):
 ...: concept = "I am a fruit"
 ...: 
In [2]: a = Fruit()
In [3]: a.concept
Out[3]: 'I am a fruit'
In [4]: Fruit.concept = "I am NOT a fruit"
In [5]: a.concept # a.concept has changed just by changing Fruit.concept
Out[5]: 'I am NOT a fruit'
answered Jan 28, 2017 at 17:41
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks @Rushy, this is very helpful. I did read over the answer you linked (and linked it in my question), but it didn't completely answer my question. Your answer does answer my question, though. Thank you so much, this is very clear and helpful.
1

After calling the class, the instance should be ready to go and not require additional attribute settings.

You left out the usual answer for when there is a sensible non-mutable default.

class Fruit(object):
 def __init__(self, concept='I am a fruit'):
 self.concept = concept
answered Jan 28, 2017 at 17:41

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.