注意标题,这里讲的是“操作变量”,而不单纯是“修改变量”,”修改“有更多方法,比如直接return一个新的值给原来的变量,也能做到“修改”的效果,而“操作”是指在函数中直接操作这个变量,用的是这个变量的值,改的也是这个变量的值,包括变量的调用、输入和输出。

在C语言中,如果想要用一个函数去操作外部的值,可以直接取变量的地址传入函数,然后通过解引用去操作外部变量。

在C++中,也可以直接用变量的引用去操作它。

但是在python里,既没有指针也没有引用(注意这里的引用不是指import,而是C++中的一种语法),那么该如何实现“在函数内部修改外部变量的值”呢?

下面举几个例子,我们一起探索。

首先讲在函数内修改全局变量:

例1:直接在函数内使用外部变量名进行操作(失败)

def func1_1():

    #这里定义一个func1_2,是为了后面验证内层函数如何修改外层函数变量,在此处并无实际作用
    def func1_2():
        a=2
        print("进入func1_2之后",a)

    #注意上面三行是我定义的内部函数,func1_1真正是从下面开始执行

    a=1
    print("进入func1_1之后,进入func1_2之前",a)
    func1_2()
    print("出了func1_2之后",a)

#注意上面是我定义的函数,真正的代码从下面开始执行

a=0
print("进入func1_1之前",a)
func1_1()
print("出了func1_1之后",a)

运行结果如下:

python内层函数调用外层函数 python函数调用外部变量_全局变量

可以看到,func1_1和func1_2并没有真正修改全局变量a的值,只是重新在函数内部定义了一个变量a,出了函数便会自动销毁掉

例2:使用global关键字(成功)

def func2_1():

    def func2_2():
        global a
        a=2
        print("进入func2_2之后",a)

    #注意上面三行是我定义的内部函数,func2_1真正是从下面开始执行

    global a
    a=1
    print("进入func2_1之后,进入func2_2之前",a)
    func2_2()
    print("出了func2_2之后",a)

#注意上面是我定义的函数,真正的代码从下面开始执行

print("进入func2_1之前",a)
func2_1()
print("出了func2_1之后",a)

 运行结果如下:

python内层函数调用外层函数 python函数调用外部变量_开发语言_02

global关键字将变量a声明为全局变量,所以可以在函数内实现对外部的全局变量a的操作,除了单纯的输出,还可以直接调用a,或对a进行输入

接下来讲在内部函数操作外部函数中定义的变量

直接看代码:

def func3_1():

    def func3_2():
        b=1
        print("进入func3_2之后",b)

    def func3_3():
        global b
        b=1
        print("进入func3_3之后",b)

    def func3_4(tmp):
        tmp=1
        print("进入func3_4之后",tmp) 

    def func3_5():
        nonlocal b
        b=1
        print("进入func3_5之后",b)

    #注意上面是对各个内部函数的定义,实际func3_1的代码从下面开始执行

    b=0
    print("进入func3_2之前",b)
    func3_2()
    print("出了func3_2之后",b)

    print("进入func3_3之前",b)
    func3_3()
    print("出了func3_3之后",b)

    print("进入func3_4之前",b)
    func3_4(b)
    print("出了func3_4之后",b)

    print("进入func3_5之前",b)
    func3_5()
    print("出了func3_5之后",b)

#注意上面是对函数func3_1的定义,实际代码从下面开始执行

print("进入func3_1之前,没有b")
func3_1()

运行结果如下:

python内层函数调用外层函数 python函数调用外部变量_开发语言_03

我们一个一个看:

我们在func3_1这个外部函数里定义了一个变量b=0

首先进入func3_2:

我们单纯地对变量名进行操作,发现出了func3_2之后外部的b值并没有变化,可知,func3_2只是重新在函数内部定义了一个变量b,出了func3_2便会自动销毁掉

 然后进入func3_3:

我们尝试用关键字global去声明b为全局变量,显然这是行不通的,因为b本来就不是全局变量,得到的结果也同样证明,外部func3_1中的b的值并没有发生变化,实际func3_3进行的操作和func3_2相同

再进入func3_4:

这个函数就是把b作为参数传进去,实际上是在函数内创建了一个和实际参数b一样的形式参数tmp,这里实现的是对tmp的操作,对b的实际值并没有任何影响

这和C/C++里的传值操作完全相同。

其实用return对b返回一个值也是相同的道理,都没有实现真正意义上对b进行操作。

最后进入func3_5:

这里我们用了一个关键字“nonlocal”,这是在python3之后新添加的一个关键字,如果一个变量既不是全局变量,也不是当前函数中的局部变量,那么用nolocal对它进行声明,就可以对其进行操作(说白了就是在内部函数操作外部函数的变量)

当然,在此之前也有一种方法,那就是将变量存储在容器中(比如列表)b=[0],这样内部函数也可以直接访问并操作b[0]

(其实在发现nonlocal这个关键字之前我一直都这么做的)