0

Why mutable objects like array or list can be visited and changed in function directly while immutable objects like number can be only visited but not changed? What is the mechnism. Below is some simple test code.

import numpy as np

a = [1,2,3]
b = np.array([1,2,3])
c = 3
def func():
    a.append(1)
    b[0] = 2
    c += 1
    print(c)
    
func()
6
  • 2
    Please do not post code as an image. Commented May 6, 2022 at 14:29
  • Show code and other textual information as properly formatted text in the question, not as image or external link. Commented May 6, 2022 at 14:30
  • I don't understand the question. This code prints 4 so clearly c was changed. (Of course you cannot change the number 3 itself but you can change variables containing that value.) Commented May 6, 2022 at 14:33
  • You seem to be asking why mutable objects are mutable but immutable objects are not mutable... Commented May 6, 2022 at 14:33
  • Thank you! .Since It's my first question, I am not familiar enough with the process. Commented May 6, 2022 at 14:34

2 Answers 2

2

The difference is whether you assign or mutate. When you mutate data, like with a.append(1), the object reference (a) is not changed: it is still the same list reference. When you assign, the variable really gets a different reference, and the object that was previously referenced does not get affected.

Without global, globals can be mutated (when they are mutable), but not assigned.

This has little to do with mutable or not, as even a = [] would not be allowed without the corresponding global statement. Even though lists are mutable, this a = [] is not attempting to mutate anything. It assigns. And that requires global.

Sign up to request clarification or add additional context in comments.

Comments

0

Well, you're kind of answering your own question.

Mutable objects are internally mutable, while immutable objects, well, aren't.

The global c (or nonlocal c in an inner function) statement tells Python that the name c refers to the name c in the global (or outer) scope.

Since integers aren't internally mutable (and don't implement __iadd__, the magic method that could back +=), c += 1 does c = c + 1, i.e. assigns the value of the expression c + 1 to the global name c.

If you attempt c += 1 in a function without the global statement, you'll get an UnboundLocalError, since there is no name c to access and increment before that assignment itself.

This stands for any name; trying to do

>>> a = []
>>> def f():
...     a = a + ["foo"]
...
>>> f()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in f
UnboundLocalError: local variable 'a' referenced before assignment

also fails, since a has not been assigned within the function.

2 Comments

Sorry,I have removed the global tag with c in my code. Why c can not be changed with global or nonlocal but mutable obejects can? Thank you, I'm a new hand in python.
By removing global c from your original question, you've made it an entirely different question, and you'll find it doesn't work anymore. The reasons why are outlined in this answer.

Your Answer

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.