Python函数范围

时间:2017-07-07 13:22:04

标签: python

我对python函数的范围有疑问。我已经包含了一个示例,说明了我遇到的问题。

fun0 重新定义了varible c 列表中的第一个条目。此更改会反映在 fun0 之外,即使我没有从 fun0 返回任何值。

fun1 完全重新定义变量 c ,但更改并未反映在 fun1 之外。同样, fun2 重新定义了 c ,并且更改并未反映在 fun2 之外。

我的问题是,为什么 fun0 修改函数中的 val3 ,而 fun1 fun2 分别不修改 val4 val7

def fun0(a, b, c):
    c[0] = a[0] + b[0]
    return

def fun1(a, b, c):
    c = a[0] + b[0]
    return

def fun2(a, b, c):
    c = a + b
    return

def main():
    val1 = ['one']
    val2 = ['two']
    val3 = ['']
    fun0(val1, val2, val3)
    print val3

    val4 = []
    fun1(val1, val2, val4)
    print val4

    val5 = 1
    val6 = 1
    val7 = 0
    fun2(val5, val6, val7)
    print val7
    return

if __name__=='__main__':
    main()

5 个答案:

答案 0 :(得分:2)

它与列表和变量的存储方式有关。您可以修改函数中的列表,因为它们是可变对象。但是,如果您执行c = a[0] + b[0],则表示您正在fun1fun2内创建一个局部变量,该变量保留在函数范围内。

答案 1 :(得分:1)

  

我的问题是,为什么fun0修改主函数中的val3,而fun1和fun2不分别修改val4和val7?

这是因为Python传递参数的方式。

当您将参数传递给函数时,Python会通过赋值传递它们。这意味着它将参数引用绑定到参数名称。这是参数和参数名称相关的唯一方法。在第一个示例中,您只是将引用传递给val3,并且由于val3c都引用了相同的列表对象,因此更改会反映在两个名称之间。

但是,当您在函数内部重新分配c时,您替换了对c所持有的列表的引用,并重新分配了c一个新引用。

答案 2 :(得分:1)

从技术上讲,当您将参数传递给函数时,您传递的是副本,而不是原始副本。现在传递列表和传递变量之间存在差异。当变量保存值时,列表包含对其他对象的引用。因此,当传递列表时,即使它被复制,它仍然引用相同的对象并且可以在函数内进行更改,但是在传递变量时,复制的对象与原始对象无关。希望这是有道理的。

答案 3 :(得分:0)

Cary Shindell绝对是正确的。此外,如果您想要保存更新的值,以下是如何更改代码来执行此操作,我更改了print语句,因为我在python 3.6.1中对此进行了测试。好问题。

def main():
    val1 = ['one']
    val2 = ['two']
    val3 = ['']
    fun0(val1, val2, val3)
    print(val3)

    val4 = []
    val4 = fun1(val1, val2, val4)
    print(val4)

    val5 = 1
    val6 = 1
    val7 = 0
    val7 = fun2(val5, val6, val7)
    print(val7)
    return

答案 4 :(得分:0)

如前所述,列表是可变的。如果您传递一个列表并对其进行修改,那么您无处不在。 这适用于fun0中的所有列表。

fun2中,您没有传递任何列表,因此cfun2内计算,但在外部无法使用。

我不确定fun1,但我认为你用c中的外部不可用的新变量覆盖fun2