此内容来自于沙行勉的《计算机科学导论-以python为舟》
函数调用的基本概念:程序语言中的函数与高中数学中的函数相似。高中函数,假设要实现z+x*y²这个计算。对于乘法计算,定义一个函数f(x,y)=x*y²,他有两个参数x和y。计算x²+y²后得到一个值,作为函数的返回值,赋给f(x,y)。这样就可以用z+f(x,y)来表示上面的运算,对于f(x,y)运算,将会调用到已经定义的函数f(x,y)=x*y²。程序语言中的函数也有参数和返回值,以及定义与调用。程序中的函数就是将一些程序语句结合在一起的部件,可以多次的调用。
函数中的变量:
局部变量:函数中的局部变量只能被这个函数访问,不能被其他函数访问。
全局变量:在函数之外被赋值的变量。
a = 10
def fun():
a = 20
print(a) #函数内a内局部变量
fun()
print(a) #函数外a为全局变量复制代码
局部变量的判断:
不出现在global语句中 (global语句为申明某个变量为局部变量)
出现在函数参数中
出现在函数参数语句中的等号左边
python函数调用:
python进行函数调用时,参数的传递都是通过赋值的方式。
def func(L1): #定义一个func()函数,参数为L1
L1.append(1) #对L1采用.append()方法,结果为[2,1],并且改变全局变量L的值(因为L1和L都指向同一个heap)
L = [2]
func(L) #func()函数运行,参数为L,进行赋值传递给func()函数中的局部变量L,
print(L) func()函数执行完后,局部变量L1指向全局上的值[2,1],L也指向这个全局上的值[2,1](L1与L指向同一块内存区域)复制代码
其中列表做参数时,传递的是指针,函数中的参数指向的内容为全局变量区域,成为heap。
stack-栈,heap-堆
注意事项:
列表的append、pop、remove等方法,以及给L[i]赋值,对L[i]使用增强赋值等,都会修改列表L所指向的内容,进而对全局产生影响。
列表的一般合并,或者使用列表的分片(即L[i:j]这种形式)都不会对全局的列表L产生影响。合并与分片的操作会产生新的列表,赋值到一块新的内存区域(heap)上。
return(L)返回L的指针:
def F1():
L = [3,2,1,] #L是局部变量,而[3,2,1]是在栈的外面heap上。
return(L)
L = f1()
print("L=",L)复制代码
全局变量L调用f1()函数,f1()函数中的局部变量L经return返回到函数外的全局变量L,此时局部变量L和全局变量L都指向同一个heap。
L做函数参数传递:
def F2(): #参数L是个指针,是存放在栈上的局部变量
L = [2,1] #此语句将函数L又赋值为[2,1]
return(L) #return(L)将局部变量L的值赋值给了主调函数的全局变量(例如L = F2(),L是主调函数,F2()则是被调函数)
def F3():
L.append(1) #L指向的是原来的全局内容,会改变全局L
L[0] = 0
L = [3,2,1]
L = F2(L);print("L=",L)
F3(L);print("L=",L) #调用F3(L)后,L的全局已经被改变复制代码
好的编程习惯:
尽量避免在函数中使用全局变量
若在函数中需要使用外部的变量,使用参数传递。
对函数调用中mutable变量(列表、字典等)