变量范围python3

时间:2016-05-06 22:03:02

标签: python-3.x recursion scope

我有

def func1(var):
    if var == 0:
       return
    else
       var = var - 1
       func1(var)

PROPOSAL = 1

def func2():
  func1(PROPOSAL)
  print(PROPOSAL)

func1的递归调用中,变量PROPOSAL是否会递减,这意味着print语句将打印0

编辑:我应该问,为什么不这样做?

2 个答案:

答案 0 :(得分:0)

func1(PROPOSAL)将返回NONE,并且不会影响全局PROPOSAL变量,因为您没有将该返回值分配给PROPOSAL

func2()只需调用func1()然后打印PROPOSAL <{1}}

范围内未更改的func1(PROPOSAL)变量

答案 1 :(得分:0)

不,PROPOSAL全局变量不会被您的代码递减。这不是因为范围,而是因为Python传递了参数。

当您调用带参数的函数时,您传递的参数的值将绑定到参数名称,就像对变量的赋值一样。如果值是可变的,通过一个名称的就地修改将通过另一个名称可见,但如果该变量是不可变的(因为int是在Python中),您将永远不会看到更改一个变量影响另一个。

这是一个以相同方式显示功能和常规分配的示例:

x = 1

y = x   # binds the y to the same value as x
y += 1  # modify y (which will rebind it, since integers are immutable)
print(x, y) # prints "1 2"

def func(z): # z is a local variable in func
    z += 1 
    print(x, z)
func(x) # also prints "1 2", for exactly the same reasons as the code above

X = [1]

Y = X  # again, binds Y to the same list as X
Y.append(2)  # this time, we modify the list in place (without rebinding)

print(X, Y)  # prints "[1, 2] [1, 2]", since both names still refer to the same list

def FUNC(Z):
    Z.append(3):
    print(X, Z)
FUNC(X)  # prints "[1, 2, 3] [1, 2, 3]"

当然,重新绑定引用可变值的变量也会导致更改不会反映在对原始值的其他引用中。例如,您使用append()Y = Y + [2]替换了代码第二部分中的Z = Z + [3]调用,原始X列表不会更改,因为这些赋值语句重新绑定YZ而不是修改原始值。

&#34;增强任务&#34;像+=-=*=这样的运营商有点棘手。如果左侧的值支持它(并且许多可变类型都支持),他们将首先尝试进行就地修改。如果该值不支持那种类型的就地修改(例如,因为它是不可变对象,或者因为不允许特定运算符),它将依赖于使用常规{{ 1}}运算符来创建一个新值(如果失败也会引发异常)。