我对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()
答案 0 :(得分:2)
它与列表和变量的存储方式有关。您可以修改函数中的列表,因为它们是可变对象。但是,如果您执行c = a[0] + b[0]
,则表示您正在fun1
和fun2
内创建一个局部变量,该变量保留在函数范围内。
答案 1 :(得分:1)
我的问题是,为什么fun0修改主函数中的val3,而fun1和fun2不分别修改val4和val7?
这是因为Python传递参数的方式。
当您将参数传递给函数时,Python会通过赋值传递它们。这意味着它将参数引用绑定到参数名称。这是参数和参数名称相关的唯一方法。在第一个示例中,您只是将引用传递给val3
,并且由于val3
和c
都引用了相同的列表对象,因此更改会反映在两个名称之间。
但是,当您在函数内部重新分配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
中,您没有传递任何列表,因此c
在fun2
内计算,但在外部无法使用。
我不确定fun1
,但我认为你用c
中的外部不可用的新变量覆盖fun2
。