[英]Python Question about Variable Scope Rules
This is a source code for Quicksort in Python I found on Wikipedia. 这是我在Wikipedia上找到的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]
My question is about scope. 我的问题是关于范围。 When I pass a as an argument in the example above, how can the function qsort possibly change the variable a in a global scope if it doesn't "call" 'global a'?
当我在上面的示例中将a作为参数传递时,如果函数qsort不“调用”“全局a”,它如何在全局范围内更改变量a ? I've been programming in python for 1 year and recently started learning C. Looks like I'm making some sort of confusion.
我从事python编程已有1年了,最近开始学习C。看起来我有点困惑。 thanks
谢谢
It doesn't rebind a
/ v
, it merely mutates it. 它不会重新绑定
a
/ v
,它只是变异了。 You don't need to declare a name global
if you're mutating the object it's bound to. 如果要更改绑定到的对象,则无需声明
global
名称。
In python a
is passed by "alias" (See Jochen's comment below). 在python中,“别名”传递了
a
(请参见下面的Jochen注释)。 Therefore, Any modifications to v will be relflected in a
. 因此,对v的任何修改都将在
a
反映出来。
EDIT: I fixed my wording thanks to the comments below. 编辑:由于下面的评论,我修正了我的措辞。
qsort
receives a reference to the list object that is also bound to a
. qsort
接收至同样绑定到列表对象的引用a
。 Within the function, the same object is bound to the local variable v
, so any modifications made via v
affect a
as well. 在函数内,同一对象绑定到局部变量
v
,因此通过v
任何修改也会影响a
。
Read up about objects, references and variables for more information. 阅读有关对象,引用和变量的更多信息。
Yes, the rebind answer is a good one. 是的, 重新绑定答案是一个很好的答案。 It might be interesting for you -- since you start C, that you might want to familiarize yourself with the terms call-by-value and call-by-reference .
对于您来说可能很有趣-自从开始使用C以来,您可能想熟悉术语“ 按值 调用”和“按引用调用” 。 Maybe knowing about those in advance will protect you from surprises:
也许提前知道这些会保护您免受意外的影响:
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.
}
Be it as it may, also in C you find, that the parameters number and pnumber will bind to the real variables x and y from the outside world. 无论如何 ,同样在C语言中,您会发现参数number和pnumber将绑定到外部的实数变量x和y 。 In Python the fact that you have a list
a = [4,2,4,6,3,2,5,1,3]
will let you change that outside a
by its inside name v
. 在Python中,您拥有列表
a = [4,2,4,6,3,2,5,1,3]
的事实将使您可以通过内部名称v
更改a
之外a
。 Just like pnumber
allowed you that in C. In comparison a tuple would not have been mutable and would have been copied, ie a = (4,2,4,6,3,2,5,1,3)
would not have worked. 就像
pnumber
允许您在C语言中进行操作。相比之下, 元组将不会是可变的,并且会被复制,即a = (4,2,4,6,3,2,5,1,3)
不会起作用。 Just like in C the number
is just a copy of x
-- and therefore x
does not change outside. 就像在C中一样,
number
只是x
的副本 -因此x
不会在外部变化。
By the way, I suggest you skip C, but go right ahead and pick up some C++. 顺便说一句,我建议您跳过C,但是继续前进并选择一些C ++。 Some things are just nicer there.
有些东西在那里更好。 For example, you can do it here without the
*pnumber
all the time: 例如,您可以
*pnumber
在此处使用*pnumber
来执行此操作:
void callByReferenceCPlusPlus(int &number) {
number = number + 1;
}
void main() {
int z = 5;
callByReferenceCPlusPlus(z);
// hooray, z is 6!
}
It might be a matter of taste, but it is really more straightforward, without thinking of the pointer-details all the time. 这可能是一个问题,但实际上更简单了,无需始终考虑指针的细节。 Really.
真。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.