Python更改变量与函数中的数组?

时间:2015-09-18 17:16:22

标签: python function methods immutability mutable

我对从函数内部改变(变异或附加)变量感到困惑 作为参考,我发现了关于functions that mutate the argument的这个问题。其中描述了在数组上执行此操作:

def add_thing(a):
    a.append(2)

my_a = [1]

append_two(my_a)
my_a
>>> [1,2]

我们使用+ = [2]

得到相同的结果

但是,如果我们使用字符串或整数尝试相同的事情:

def add_world (s):
    s += " world"

my_str = "hello"

add_world(my_str)
my_str
>>> "hello"

它不会改变,整数也是如此,例如:

def add_one(i):
    i += 1

x = 1
add_one(x)
x
>>> 1

我的问题是:

  1. 我应该如何识别我可以在像数组这样的函数中变异的对象,以及我需要直接分配哪些对象?

  2. 为什么+ =运算符不能像我期望的那样工作?我很确定这是my_var = my_var + thing的简写,它可以在一个函数中正常工作。

2 个答案:

答案 0 :(得分:2)

  1. 您必须查看文档。通常:数字,字符串和tuple是不可变的。

    关于特定方法,还有一个通用规则:如果方法返回,那么它不会修改参数。修改参数的方法返回None

  2. 如果a += b不可变,则
  3. a = a + b相当于a。如果a是可变的,则使用+=将改变对象。基本上+=只是一个方法调用(到__iadd__)。在不可变对象的情况下,该方法返回一个新对象并且不会改变原始值,对于可变对象,该对象是变异的并且它自己返回。

答案 1 :(得分:2)

  

我应该如何识别我可以在像数组这样的函数中变异的对象,以及我需要直接分配哪些对象?

您需要知道您正在使用的对象类型,并阅读这些对象的文档,以了解哪些操作(如果有)会改变它们。不幸的是,在list的情况下,这并没有以最容易获得的方式记录。最接近的是this,其中说:

  

x += 1这样的扩充分配表达式可以重写为x = x + 1,以实现类似但不完全相同的效果。在增强版本中,x仅评估一次。此外,在可能的情况下,实际操作是就地执行的,这意味着不是创建新对象并将其分配给目标,而是修改旧对象。

由于列表是可变的,这意味着可以进行就地操作。

  

为什么+ =运算符不能像我期望的那样工作?我很确定这是my_var = my_var + thing的简写,它可以在函数中正常工作。

如上面的引用所示,a += ba = a + b并不完全相同。不同之处在于,对象a有机会为a += b定义可能与a + b的行为不同的特殊行为。列表执行此操作以使+=就地工作。