Изменяемая область видимости Python и неизменяемость - PullRequest
5 голосов
/ 07 декабря 2011

Сначала я собираюсь начать, как и все остальные. Я новичок в питоне. Мой учитель поставил мне задачу:

def f(a, b, c):  
    a    = 1 
    c    = b 
    c[0] = 2 
a = 10 
b = [11, 12, 13] 
c = [13, 14, 15] 
f(a, b, c) 
print a, b, c

Он печатает:

10 [2, 12, 13] [13, 14, 15]

Я понимаю, что a остается в 10, потому что целые числа неизменны, но я не понимаю, почему b меняется, а c нет.

Ответы [ 3 ]

4 голосов
/ 07 декабря 2011
c    = b 
c[0] = 2

Поскольку вы устанавливаете c для указания на b, вы можете сделать это так же просто:

def f(a, b, unused): # notice c isn't in the parameter list  
    a = 1
    c = b # c is declared here
    c[0] = 2 # c points to b, so c[0] is b[0]

Теперь очевидно, что c всегда совпадает с b, так почему бы просто не удалить его:

def f(a, b, unused):
    a = 1
    b[0] = 2

И теперь ясно, что вы меняете первый элемент b и ничего не делаете на c, и помните, что это функционально идентично оригиналу.

2 голосов
/ 07 декабря 2011

Ключ должен понимать переменные как указатели под капотом:

def f(a, b, c):  
    a    = 1 # a is a single scalar value, so no pointing involved
    c    = b # point the local "c" pointer to point to "b"
    c[0] = 2 # change the 2nd value in the list pointed to by "c" to 2

Когда вы вызываете f (a, b, c), только b фактически изменяется.Переменная «c» внутри реализации функции отличается от реализации «c» вне функции.

0 голосов
/ 07 декабря 2011

a не сохраняет значение 10, поскольку оно является неизменным.Он сохраняет значение 10, поскольку при вызове a = 1 в локальной области действия f() создается новая переменная.

При вызове c = b внутри f() локальный c становитсялокальная ссылка на изменяемый объект, представленный b.Когда вы переназначаете значения в этом изменяемом объекте, изменение отражается в исходном объекте.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...