Python关于变量范围规则的问题

时间:2011-02-15 18:57:36

标签: python scope quicksort

这是我在维基百科上找到的Python中Quicksort的源代码。

def pivot(v, left, right):
    i = left
    for j in range(left + 1, right + 1):
        if v[j] < v[left]:
            i += 1 # .. incrementa-se i
           v[i], v[j] = v[j], v[i]
    v[i], v[left] = v[left], v[i]
    return i

def qsort(v, left, right):
    if right > left:
        r = pivot(v, left, right)
        qsort(v, left, r - 1)
        qsort(v, r + 1, right)

a = [4,2,4,6,3,2,5,1,3]
qsort(a, 0, len(a)-1)
print a # prints [1, 2, 2, 3, 3, 4, 4, 5, 6]

我的问题是关于范围。当我在上面的示例中将 a 作为参数传递时,如果函数 qsort 可能会更改全局范围内的变量 a “t”称“'全球''?我已经在python中编程了1年,最近开始学习C.看起来我正在制造某种混乱。 感谢

4 个答案:

答案 0 :(得分:6)

它不会重新绑定 a / v,它只是变异它。如果要改变它所绑定的对象,则不需要声明名称global

答案 1 :(得分:2)

在python a中通过“alias”传递(参见Jochen的评论如下)。因此,对{v的任何修改都将在a中重新选择。

编辑:由于以下评论,我修改了我的措辞。

答案 2 :(得分:0)

qsort接收对同样绑定到a的列表对象的引用。在函数内,同一个对象绑定到局部变量v,因此通过v进行的任何修改也会影响a

阅读有关对象,参考和变量的信息,以获取更多信息。

答案 3 :(得分:0)

是的,重新绑定答案很好。它可能对您有意义 - 因为您启动C,您可能希望熟悉术语按值调用按引用调用。也许提前了解这些将保护您免受意外:

void callByValue(int number) {
    number = number + 1;
}

void callByReference(int *pnumber) {
    *pnumber = *pnumber + 1;
}

void main() {
    int x = 5;
    callByValue(x);
    // here, x is still 5

    int y = 5;
    callByReference(*y);
    // here, y is now 6.
}

尽管如此,在你发现的C中,参数 number pnumber 绑定到真正的变量 x 和 y 。在Python中,您有一个列表a = [4,2,4,6,3,2,5,1,3]的事实将允许您通过其内部名称av之外更改它。就像pnumber允许你在C中一样。相比之下,元组不会是可变的并且会被复制,即a = (4,2,4,6,3,2,5,1,3)不会有效。就像在C中一样,number只是x副本 - 因此x不会在外部发生变化。

顺便说一句,我建议你跳过C,但是请继续前进并选择一些C ++。有些事情在那里更好。例如,您可以在此处不使用*pnumber来执行此操作:

void callByReferenceCPlusPlus(int &number) {
    number = number + 1;
}

void main() {
   int z = 5;
   callByReferenceCPlusPlus(z);
   // hooray, z is 6!
}

这可能是一个品味问题,但它实际上更直接,而不是一直想着指针细节。真。