简体   繁体   English

Python作用域可变与不可变

[英]Python scoping mutable vs immutable

First I'm going to start like everyone else. 首先,我将像其他所有人一样开始。 I'm new to python. 我是python的新手。 My teacher gave me the problem: 我的老师给了我一个问题:

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

It prints: 它打印:

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

I understand that a stays at 10 because integers are immutable, but I don't understand why b changes and c doesn't. 我知道a保持为10是因为整数是不可变的,但是我不明白为什么b改变而c不变。

c    = b 
c[0] = 2

Since you're setting c to point to b , You could just as easily do this: 由于将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]

Now it's obvious that c is always the same as b , so why not just remove it: 现在很明显, c始终与b相同,所以为什么不删除它:

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

And now it's clear that you're changing the first element of b and not doing anything to c , and remember, this is functionally identical to the original. 现在很明显,您正在更改b的第一个元素,而不对c进行任何操作,请记住,这在功能上与原始功能相同。

The key is to understand the variables as pointers under the hood: 关键是将变量理解为幕后的指针:

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

When you call f(a,b,c), only b actually gets changed. 当您调用f(a,b,c)时,实际上只有b被更改。 The "c" variable inside the function implementation is different from the "c" implementation outside the function. 函数实现内的“ c”变量不同于函数外的“ c”实现。

a does not retain the value of 10 because it is immutable. a不会保留10的值,因为它是不可变的。 It retains the value of 10 because when you call a = 1 in the local scope of f() you create a new variable. 它保留10的值,因为在f()的局部范围内调用a = 1 ,会创建一个新变量。

When you call c = b inside f() , the local c becomes a local reference to the mutable object represented by b . 当在f()调用c = b ,局部c成为对b表示的可变对象的局部引用。 When you re-assign the values in that mutable object the change is reflected in the original object. 当您在该可变对象中重新分配值时,更改将反映在原始对象中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM