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