首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >函数中的变量更改- Python 3

函数中的变量更改- Python 3
EN

Stack Overflow用户
提问于 2019-06-15 17:13:14
回答 2查看 322关注 0票数 1

所以我得到了以下代码:

代码语言:javascript
复制
def foo(a, b, c):
    try:
        a = [0]
        b[0] = 1
        c[0] = 2
        w[0] = 3
    except:
        pass
    return z

x, y, z = [None], [None], [None]
w = z[:]
foo(x,y,z)
print(x,y,z,w)

print(x,y,z,w)代码的最后一行打印[None] [1] [2] [3],但是我不太明白。为什么x,y,z在功能上被改变了?如果w改变了--它指向了z,为什么z不相应地改变呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-06-15 17:20:33

在Python中,对象通过引用函数传递。此行生成z的副本

代码语言:javascript
复制
w = z[:]

因此,对z的更改不会影响w,反之亦然。排在队伍里

代码语言:javascript
复制
a = [0]

将引用更改为指向一个新对象,这样就不会更改x (这是a最初绑定的对象)。在以下几行

代码语言:javascript
复制
b[0] = 1
c[0] = 2

您更改了引用的对象(全局范围中的yz ),因此外部作用域中的对象发生了变化。排在队伍里

代码语言:javascript
复制
w[0] = 3

您可以变异全局对象w,因为名称w不是函数的参数,也不绑定到函数的正文中。

票数 4
EN

Stack Overflow用户

发布于 2019-06-15 17:45:08

其他人说的都是正确的,但我想补充一下,如果您有使用C或C++这样的语言的经验,我的思维方式可能会有所帮助。

中的每个变量都是指针(技术术语是“引用”,但我发现这比“指针”更难可视化)。您知道在C/C++中如何通过传递指针来获得输出多个值的函数吗?您的代码基本上是在做相同的事情。

当然,您可能想知道,如果是这样的话,为什么您没有看到ints、strs或诸如此类的事情发生呢?原因是这些东西是不可变的,这意味着您根本无法直接更改intstr的值。当您“更改一个整数”(如i = 1 )时,您实际上是在更改变量,将其指向另一个int对象。类似地,s += 'abc'使用值s + 'abc'创建一个新的str对象,然后将其分配给s。(这就是为什么当s += 'abc'很长时,s可能效率很低,而不是附加到列表中!)

注意,当您执行a = [0]时,您正在以第二种方式更改a --更改指针而不是指向的对象。这就是为什么这一行不修改x的原因。

最后,正如其他人所说的,w = z[:]复制了一份。这可能有点令人困惑,因为对于其他一些对象(如numpy数组),这个语法生成一个视图而不是一个副本,这意味着在更改元素时,它的作用类似于同一个对象。请记住,[]只是一个运算符,每种类型的对象都可以选择赋予它不同的语义意义。就像%int的模式,str的格式一样--有时候你只需要熟悉不同类型的特性。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56612509

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档