1

Which of the following cases is the best practice way of declaring an instance variable in python. Is there a typical preference, and what are the justifications for this?

Option 1 - Declare within __init__

class MyObject:

    def __init__(self, arg):
        self.variable_1 = self.method_1(arg)

    def method_1(self, arg):
        return(arg)

Option 2 - Declare in other methods

class MyObject:

    def __init__(self, arg):
        self.method_1(arg)

    def method_1(self, arg):
        self.variable_1 = arg

This is purely to understand if there is a best practice way of doing this that other developers would prefer to see when reviewing and extending code.

datavoredan
  • 3,536
  • 9
  • 32
  • 48
  • Option 1. You should declare all attributes in `__init__` because that it where someone will look for them. – Klaus D. Mar 07 '17 at 09:20
  • The general rule in OOP (irrespective of the programming language) is the constructor is like an assignment operator means in __init__ we should assign the values of instance variables. So I think we should assign the values in __init__ and getter and setter should be separated from it. – Muhammad Haseeb Khan Mar 07 '17 at 09:26
  • 2
    I apologize for being pedantic, but instance variables are not declared in Python. They [spring into existence](https://docs.python.org/3.3/tutorial/classes.html#instance-objects) when they are first assigned to. Variable declaration exists in languages like C++ and Java, not in Python. – juanpa.arrivillaga Mar 07 '17 at 09:44
  • Good point @juanpa.arrivillaga. You may note I carefully avoided using the word "declare" in my answer. :) I'm also trying to get out of the habit of using the word "variable" in Python, but it's just too convenient... – PM 2Ring Mar 07 '17 at 09:57

4 Answers4

0

This is obviously not exact science, but it generally makes more sense to set all attributes (as possible) in the constructor so that you can follow up on them.

You can, of course, change them later as necessary in other methods.

Setting constructor level variables everywhere in the class makes it very hard to understand where things are coming from.

nir0s
  • 1,151
  • 7
  • 17
0

Option 1 is best practice to declare instance variable in Python. Instance variables are for data that is actually part of the instance so it would be better if you define in constructor.

Harsha Biyani
  • 7,049
  • 9
  • 37
  • 61
0

Your Option 2 is basically a Setter-/Getter-Paradigm. Python uses properties for these use-cases. There's a nice SO-answer for a similar question.

In general you initialize all your Instance-variables in the __init__-method, that's its reason to exist. If you need a getter-/setter use properties. And use the "least-astonishment" principle. Do not surprise another reader, or your later self with overly clever and/or complicated solutions. (aka KISS principle)

Community
  • 1
  • 1
Don Question
  • 11,227
  • 5
  • 36
  • 54
0

It depends. Defining all the attributes inside __init__ itself generally makes the code more readable, but if the class has a lot of attributes and you can easily divide them into logical groups then it makes sense to initialise each group of attributes in its own initialising method. You may wish to indicate that such methods are private by giving them a name that commences with a single underscore.

Note that if the class is derived from one or more other classes (apart from object) then you will have to call super.__init__ to initialise the attributes inherited from the parent class(es).

The bottom line is that all instance attributes should exist by the time that __init__ finishes executing. If it's not possible to set a proper value for some attribute in __init__ then it should be set to an appropriate default value, eg an empty string, list, etc, None, or a sentinel value like object().

Of course, the above doesn't apply to @property attributes, but even those will generally have an underlying "private" attribute that should be set in __init__.

For more info about properties, please see Raymond Hettinger's excellent Descriptor HowTo Guide in the Python docs.


As juanpa.arrivillaga mentions in the question comments, we don't actually declare variables in Python. That's basically because the Python data model doesn't really have variables like C and many other languages do. For a succinct explanation with nice diagrams please see Other languages have "variables", Python has "names". Also see Facts and myths about Python names and values, which was written by SO veteran Ned Batchelder.

Community
  • 1
  • 1
PM 2Ring
  • 54,345
  • 6
  • 82
  • 182