2

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?

kingwales
  • 129
  • 8
  • 1
    Because both `self` and `lst` are mutable but `num` on its own is not. `self.num += 1` is mutating the instance. `num += 1` is assigning a new `int` object to `num`. – Axe319 Jan 19 '22 at 18:26
  • 1
    Thanks. i got it now. – kingwales Jan 19 '22 at 18:32
  • 3
    Note that `self` is not a keyword: it is just the name conventionally given to the first parameter that references to the instance – azelcer Jan 20 '22 at 01:35

3 Answers3

2

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
2pichar
  • 1,348
  • 4
  • 17
  • I don't think you get my question. I am asking why ```lst``` does not need ```self```, but ```num``` needs it.. – kingwales Jan 19 '22 at 18:19
  • Because `lst` is a local variable to the function, while `num` is a property of the instance – 2pichar Jan 19 '22 at 18:21
  • That's why if you call `i = test(); i.func(); i.test()`, it throws an error because `lst` doesn't exist. `lst` is local to `func` – 2pichar Jan 19 '22 at 18:23
  • @2pichar if you look at OP's question, the `method` function is an inner function and not an actual method. Your example just has 2 methods. – Axe319 Jan 19 '22 at 18:38
1

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.

Tim Roberts
  • 48,973
  • 4
  • 21
  • 30
1

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!
Robin Dillen
  • 704
  • 5
  • 11