首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >奇异变量操纵行为

奇异变量操纵行为
EN

Stack Overflow用户
提问于 2013-08-27 23:51:00
回答 2查看 99关注 0票数 0

当我有一个功能像

代码语言:javascript
复制
def foo(A):
    tmp=A
    tmp=tmp+1
    *rest of the function*
    return

代码语言:javascript
复制
def foo(A):
    global tmp
    tmp=A
    tmp=tmp+1
    *rest of the function*
    return

同时添加到"A“和"tmp”1,而不是只添加到"tmp“。我做错了什么,我该如何解决呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-08-28 00:00:17

正如nneonneo在Blake的回答(它描述了问题的重要部分)下的评论所指出的,最初文章中的代码实际上并没有做他所说的事情。例如:

代码语言:javascript
复制
def foo(A):
   tmp = A
   tmp = tmp + 1
   return (A, tmp)

foo(3)

返回(3,4),意味着A保持不变。

如果这不是真,那就是A是可变类型。可变类型包括列表、字典和派生类型,而整数、浮点数和元组是不可变的。

例如:

代码语言:javascript
复制
def foo(A):
   tmp = A
   tmp[0] = tmp[0] + 1
   return (A, tmp)

foo([1, 2])

返回([2, 2], [2, 2]),在本例中,A已更改。

foo更改列表大小写中A的值,但不更改整数大小写,因为列表是可变的,整数不是可变的。当A是可变类型时,将A赋值给tmp,将引用分配给可变对象,而更改其元素之一(如tmp[0] = tmp[0] + 1中的元素)并不构成新对象。

例如,如果您不希望您的函数对列表具有类似于副作用的行为,一个常见的Python成语是使用片表示法复制列表。当您将新的list对象赋值给tmp时,它将成为一个新的列表对象,tmp是A中列表对象的副本:

代码语言:javascript
复制
def foo(A):
   tmp = A[:]
   # this slice makes a new list, a copy of A

   tmp[0] = tmp[0] + 1
   return (A, tmp)

foo([1, 2])

这将返回([1, 2], [2, 2]),因此A不变,tmp被更改。

还有其他复制列表或其他可变对象的方法,它们彼此之间有细微的不同。How to clone or copy a list?对您的选择有很好的描述。

票数 0
EN

Stack Overflow用户

发布于 2013-08-27 23:53:00

这是因为python方法参数是通过引用传递的,而不是通过值传递的。本质上是在修改内存中的相同位置,这是两个不同的变量指向的位置。

代码语言:javascript
复制
>>> def foo(a):
    tmp = a
    print(tmp, a, id(a), id(tmp))
>>> foo(5)
5 5 505910928 505910928
>>> b = 5
>>> foo(b)
5 5 505910928 505910928
>>> id(b)
505910928

以全球为例:

代码语言:javascript
复制
>>> def foo(a):
    global tmp
    a = tmp
    print(a, tmp, id(a), id(tmp))
>>> foo(5)
7 7 505910960 505910960
>>> foo('s')
7 7 505910960 505910960
>>> tmp
7
>>> tmp = 6
>>> foo('a')
6 6 505910944 505910944
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18477243

复制
相关文章

相似问题

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