In what cases should i use self keyword?

Viewed 62

I have a simple question but which confuses me for a long time. This is the example code:

class test():
    def func(self):
        
        lst = []
        self.num = 0
        
        def method(tmp):
            lst.append(tmp)
            self.num += 1
        
        method(1)

The question is, why do I need to add self before num, but for lst, i dont need to do that?

self.num is making num global inside func?

3 Answers

self is a reference to the instance of the class. So, self.num is referencing the property num on the instance, while lst is a local variable to that method.

class test:
    def func(self):
        self.lst = [0, 1, 2, 3]
        lst = [5, 6, 7, 8]
        print(self.lst) # [0, 1, 2, 3]
        print(lst) # [5, 6, 7, 8]

    def test(self):
        print(self.lst) # [0, 1, 2, 3]
        print(lst) # Error

i = test()
i.func()
i.test() # Error, see above

func is member function of the class. method is just a standalone function, unrelated to the class. In order to call func, you have to say:

obj.func()

Python handles that by automatically passing the obj as the first parameter, which we have traditionally called self. But to call method, you just say:

method(1)

There is no object, so there is no automatic creating of a first parameter. When you refer to self and num inside of method, you're referring to the local variables in the outer function, which it inherits.

Without the self the code doesn't work because Immutable vs Mutable types, But this code will:

class test():
    def func(self):
        
        lst = []
        num = 0
        
        def method(tmp):
            nonlocal num
            lst.append(tmp)
            num += 1
        
        method(1)

This is because a list is mutable, and so it will not make a copy when editing the value of lst. While when the value of num is changed, it will make a new variable (local num). see docs nonlocal

Note you cannot access num outside of func. So this will not work(while it previously would)

t = test()
t.func()
print(t.num) # doesn't exist!
Related