Search code examples
pythonclassoop

Specify attributes in constructor in Python


I'm confused about the differences of the following codes:

class car:
    def __init__(self, weight):
        self.weight = weight

class car:
    def __init__(self, weight):
        self.weight = 0

class car:
    def __init__(self, weight=0):
        self.weight = weight

class car:
    def __init__(self, weight=0):
        self.weight = 0

class car:
    def __init__(self, weight=0):
        self.weight = 1

class car:
    def __init__(self):
        self.weight = 0

My understanding it's that if I specify weight=0 in def __init__(self, weight=0), then the default attributes is 0. But it seems that I can also do the similar if I don't specify def __init__(self, weight) but add self.weight = 0 afterwards. What's the difference? What if we give two different values?


Solution

  • You get confused by concepts of function arg, default value for the arg, and member variable, you are mixing them so badly.

    Function argument

    For def __init__(self,weight) you are expecting a variable passed in when calling the constructor, which is given the name "weight". It is a function argument.

    Default value for function argument

    For def __init__(self,weight=0), you are still expecting a variable passed in, but you are fine if it's absent, in which case the default value 0 will be simply assigned to symbol "weight". This is a default value for a function argument.

    Member attribute

    Now for the code below:

    class car:
    def __init__(self, weight=0):
        self.weight = weight
    

    It's effectively saying, pass me a variable, I'll assign it to a symbol "weight", otherwise I'll assign 0 to the symbol. And I'll assign the value of symbol "weight" to "self.weight", they locate at totally different scopes and hence are different symbols. It's not like C++ when you do memberwise initialization. "self.weight" is an attribute of instances of the class.

    weight vs self.weight

    Hopefully that, now for the one last example, the logic will be clear enough:

    class car:
        def __init__(self, weight=0):
            self.weight = 1
    

    Here you are getting a symbol named "weight", no matter by default or passed-in, it gets simply ignored, i.e., not referred anywhere, instead, you assign a 1 to member variable self.weight.