代码之家  ›  专栏  ›  技术社区  ›  Sergeant_Quickscoper

类型的可变性对变量的作用域有影响吗?

  •  1
  • Sergeant_Quickscoper  · 技术社区  · 2 周前

    我在玩全局变量和局部变量,注意到列表和整数有一些不同。

    当我按预期运行下面的代码时,将为整数类型创建两个不同的局部和全局变量。

    a = 10
    def fun(a):
        a = a + 1
        print(a)
        print(id(a))
    
    fun(a)
    print(a)
    print(id(a))
    
    

    但当我对一个列表做同样的事情时,会发生一些非常奇怪的事情。在下面的代码中,函数内部和外部的变量具有相同的id。

    a = [10, 12]
    def fun(a):
        a *= 3
        print(a)
        print(id(a))
    
    fun(a)
    print(a)
    print(id(a))
    
    

    这可能是我想的一个解释,如果有人知道的话,我很想知道原因,但当我对第3行做了一个很小的更改,我无法说出原因时,情况会变得更疯狂。下面的代码将再次具有不同的全局和局部变量。

    a = [10, 12]
    def fun(a):
        a = a * 3
        print(a)
        print(id(a))
    
    fun(a)
    print(a)
    print(id(a))
    
    

    如果有人能解释为什么列表会改变事情,以及为什么不使用缩写运算符来改变事情,我们将不胜感激!我正在运行Python 3.10.6。

    1 回复  |  直到 2 周前
        1
  •  1
  •   Maygon    2 周前

    在Python中,整数是不可变的对象,这意味着当您将整数传递给函数时,会创建该整数的新副本。这就是为什么在第一个代码片段中可以看到全局变量和局部变量的不同ID。

    另一方面,列表是Python中可变的对象。当您使用 *= 运算符,您正在原地修改原始列表。这意味着全局变量和局部变量都指向同一列表对象,因此它们具有相同的ID。

    当您使用 * 运算符而不是 *= 在列表上,将创建一个新的列表对象并将其分配给局部变量 a 这就是为什么您在第三个代码片段中看到全局变量和局部变量的不同ID。

    总之,代码中整数和列表之间的行为差异是由于Python中列表的可变性造成的。整数对象是不可变的,因此当传递给函数时,它们的行为与列表等可变对象不同。