python与函数的故事(局部变量,全局变量和递归函数)

局部变量与全局变量
局部变量:即在函数内定义的变量,对于不同的函数,可以定义相同名称的变量值,而且每个变量并不影响,局部变量用于临时保存数据因而在函数中定义变量来进行存储.

def tets1():
    a=300                 #创建局部变量a并赋值
    print("----test1----修改前-- a=%d"%a)
    a=200                  #将200赋值给a变量
    print("----test1----修改后-- a=%d"%a)

def test2():
    a=400                #创建局部变量a,但和第一个函数中创建的变量a无关
    print("----test2----- a=%d" %a)
tets1()
test2()

全局变量:如果一个变量,既能在一个函数中使用,也能在其他的函数中使用,这样的变量就是全局变量(另一种解释:如果该变量在函数体外,并且在调用函数之前被创建,那么这个变量就为全局变量)

全局变量能够在所有的函数中进行访问,如果全局变量和局部变量名字相同,那么使用局部变量(强龙压不过地头蛇)

a=100           #定义全局变量
def test1():
    print(a)

def test2():
    print(a)

test1()             #调用函数test1
test2()             #调用函数test2()

运行结果:

100
100

使用return获取其他函数中的局部变量

def get_wendu():        #定义函数
    wendu=33             #设置局部变量
    return wendu          #将局部变量的值返回给调用函数

def print_wendu(result):          #设置形参result用来接收实参的值
    print("温度是:%d"%result)

result = get_wendu()       #经过return返回后该函数值为变量wendu的值,并将其赋值给变量result,即result=33
print_wendu(result)      #调用print_wendu这个函数,将result作为实参传递给该函数,程序输出结果为:"温度是:33"

全局变量和局部变量名字相同问题

a=100   #定义全局变量
def test1():
    a=300         #定义局部变量a
    print("------test1------修改前--a=%d"%a)
    a=200          #修改局部变量a的值
    print("------test1------修改后--a=%d"%a)
def test2():
    print("------test2--------a=%d"%a)
test1()            #调用函数test1
test2()             #调用函数test2

程序输出结果为:

------test1------修改前--a=300
------test1------修改后--a=200
------test2--------a=100

注:当函数被调用后,便开始返回去执行函数体,程序一步一步向下执行,当需要某个变量的时候,程序会先去寻找局部变量,如果有局部变量,那么直接就调用局部变量的值,如果没有局部变量,那么就去找全局变量获取该变量的值,如果都没有,程序返回该变量未被定义,程序报错结束.

对于函数test1来说,在程序遇到test1()的时候,便返回从定义test1函数的那段代码执行,首先创建了局部变量a,然后当需要输出变量a的时候,程序首先去找局部变量a,并输出,下一步局部变量改变,程序仍然寻找局部变量a,此时a=200,对于函数test2来说,当程序遇到了test2()的时候,便返回从定义test2函数的那段代码开始执行,当需要变量a的时候,该程序内未定义局部变量a,那么该程序会寻找到全局变量a=100,并且输出,即第二个函数的输出值为100,这个为全局变量的值

修改全局变量
法一:

a=100   #定义全局变量

def test1():                  #定义函数test1
    global a                  #使用global函数声明变量a为全局变量,那么对于变量a来说,它在这个函数体内一直是全局变量,那么给其赋值,全局变量a的值也将改变,
    print("------test1------修改前--a=%d"%a)
    a=200
    print("------test1------修改后--a=%d"%a)
def test2():                  #定义函数test2
    print("------test2--------a=%d"%a)
test1()                 #调用函数test1
test2()                 #调用函数test2

输出的结果为:

------test1------修改前--a=100
------test1------修改后--a=200
------test2--------a=200

法二(简单粗暴)

a=100   #定义全局变量
a=500    #修改全局变量的值
def test1():
    global a
    print("------test1------修改前--a=%d"%a)
    a=200
    print("------test1------修改后--a=%d"%a)
def test2():
    print("------test2--------a=%d"%a)
test1()
test2()

运行结果为:

------test1------修改前--a=500
------test1------修改后--a=200
------test2--------a=200

递归函数
概念:在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。

举个例子,我们来计算阶乘 n! = 1 * 2 * 3 * … * n,用函数 fact(n)表示,可以看出:

fact(n) = n! = 1 * 2 * 3 * ... * (n-1) * n = (n-1)! * n =  n * fact(n-1) 

于是,fact(n)用递归的方式写出来就是:

def fact(n):
    if n==1:
        return 1
    return n * fact(n - 1)

所以,fact(n)可以表示为 n * fact(n-1),只有n=1时需要特殊处理。
上面就是一个递归函数。可以试试:

>>> fact(1)
1
>>> fact(5)
120
>>> fact(100)
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000L

如果我们计算fact(5),可以根据函数定义看到计算过程如下:

===> fact(5)
===> 5 * fact(4)
===> 5 * (4 * fact(3))
===> 5 * (4 * (3 * fact(2)))
===> 5 * (4 * (3 * (2 * fact(1))))
===> 5 * (4 * (3 * (2 * 1)))
===> 5 * (4 * (3 * 2))
===> 5 * (4 * 6)
===> 5 * 24
===> 120

递归函数的优点是定义简单,逻辑清晰。理论上,所有的递归函数都可以写成循环的方式,但循环的逻辑不如递归清晰。

使用递归函数需要注意防止栈溢出。在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。可以试试计算 fact(10000)。

猜你喜欢

转载自blog.csdn.net/qq_39353923/article/details/82150869
今日推荐