如何通过局部函数修改外部函数变量?Python变量传递疑问
为什么无法修改函数内的变量,以及如何解决
首先咱们拆解你遇到的问题:你以为把e作为参数传给helper函数就能修改f里的e,但实际上没生效——这是因为Python的参数传递规则和不可变类型的特性在起作用。
问题根源:不可变类型的"传引用"不等于"可修改"
Python的参数传递是「传对象引用」,但这并不意味着你能直接修改原变量——尤其是当变量是不可变类型(比如整数、字符串、元组)的时候。
看你的代码细节:
def f(): e = 70 print(e) # prints 70 def helper(e): print(e) # prints 70 e = 100 print(e) # prints 100 helper(e) # function called to change e print(e) # Still prints 70 :( Why? f() # prints 70, 70, 100, 70
当你调用helper(e)时,确实把f里e的引用传给了helper的参数e。但整数是不可变的,当你在helper里执行e = 100时,并不是修改原来的70对象,而是创建了一个全新的整数100,然后让helper内部的局部变量e指向这个新对象。这时候f里的e依然指向原来的70,自然不会发生变化。
几种实现修改的方法
方法1:用可变对象包裹变量
可变对象(比如列表、字典)的内容可以被修改,且引用本身不会改变:
def f(): e = [70] # 用列表包裹整数 print(e[0]) # prints 70 def helper(e_list): print(e_list[0]) # prints 70 e_list[0] = 100 # 修改列表内容,而非重新赋值引用 print(e_list[0]) # prints 100 helper(e) print(e[0]) # Now prints 100! f() # prints 70,70,100,100
方法2:让helper返回修改后的值,在f里重新赋值
这是处理不可变类型最常用、最清晰的方式:
def f(): e = 70 print(e) # prints 70 def helper(val): print(val) # prints 70 val = 100 print(val) # prints 100 return val # 返回修改后的值 e = helper(e) # 接收返回值,重新赋值给f里的e print(e) # prints 100 f() # prints 70,70,100,100
方法3:使用nonlocal关键字(针对嵌套函数)
因为helper是f内部的嵌套函数,可以用nonlocal声明要修改外层函数的变量,这样连参数都不用传:
def f(): e = 70 print(e) # prints 70 def helper(): nonlocal e # 声明e是外层函数f的变量 print(e) # prints 70 e = 100 print(e) # prints 100 helper() print(e) # prints 100 f() # prints 70,70,100,100
内容的提问来源于stack exchange,提问作者Saurav Yadav
相关产品推荐
相关产品推荐

