【发布时间】:2016-04-16 15:37:30
【问题描述】:
我以为我对 Python 的变量作用域理解得很好,但是今天我碰到了这段代码。
from __future__ import print_function
def main():
v_Matrix =[[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
print(v_Matrix)
print()
f_Rotate(v_Matrix)
print(v_Matrix)
hh = 3
f_This(hh)
print(hh)
def f_Swap(v_Matrix, r1, c1, r2, c2):
v_Matrix[r1][c1], v_Matrix[r2][c2] = v_Matrix[r2][c2], v_Matrix[r1][c1]
def f_Transpose(v_Matrix):
for row in range(len(v_Matrix)):
for col in range(row):
f_Swap(v_Matrix, row, col, col, row)
def f_FlipVertical(v_Matrix):
v_Size = len(v_Matrix)
for row in range(v_Size // 2):
for col in range(v_Size):
f_Swap(v_Matrix, row, col, v_Size - row - 1, col)
def f_Rotate(v_Matrix):
f_Transpose(v_Matrix)
f_FlipVertical(v_Matrix)
def f_This(hh):
hh = hh * 2
if __name__ == '__main__':
main()
运行时,变量v_Matrix 的行为似乎是全局的。但是,测试变量 hh 的行为与预期一样,其中一个作用域位于 main() 中,另一个作用域位于 f_This 中。
v_Matrix 不是全局的,在各个函数中被修改,但不会在这些函数之间来回传递,甚至不会返回到main()。然而,在这些函数中应用于v_Matrix 的值更改可以在main() 范围内访问,如输出之间所示。但是,正如预期的那样,测试变量hh的值在main()范围内没有变化,只是在函数的范围内。
什么给了?
【问题讨论】:
-
那是因为列表是可变的。有关详细讨论,请参阅docs.python.org/2/reference/…。
-
并且Python在调用函数时将指向可变对象的指针作为参数传递,而不是创建对象的副本。与 C 风格的指针一样,您可以修改所指向对象的内容,但不能通过赋值使函数的调用者指向新对象。
-
@Selcuk 好的,关于您的链接中的范围没有太多提及。但是,您的评论确实帮助我指出了这样一个事实,即可变对象,尤其是列表在基于“外部”与“内部”容器等的范围方面具有不同的行为。我还不完全理解,但我会.我想我在研究范围时错过了这个事实。谢谢。
-
@Matt Jordan 感谢您的评论和 Selcuk 的评论,我正在处理它。我迷路了,现在我找到了。谢谢。
-
@JayJay123,可变和不可变对象没有基于范围的不同行为。它们以完全相同的方式传递给函数。只是可变对象可以就地更改,而不可变对象则不能。例如,
hh=hh*2不会改变现有的包含 3 的整数对象,而是将名为的本地hh重新分配给另一个包含 6 的整数对象。外部的hh名称仍然引用 3。对于矩阵,有一个将名为v_Matrix的外部变量和内部变量分配给列表,并且列表对象就地更改。