- 前言
- 一、函数的创建和调用
- 二、函数的参数传递
- 三、函数的返回值
- 四、函数的参数定义
- 1、函数定义默认值参数
- 2、个数可变的位置参数
- 3、个数可变的关键字形参
- 五、变量的作用域
- 六、递归函数
- 总结
前言
函数就是执行特定任务和完成特定功能的一段代码
为什么需要函数?
- 复用代码
- 隐藏实现细节
- 提高可维护性
- 提高可读性便于调试
一、函数的创建和调用
def calc(a, b): # 函数
c = a + b
return c
result = calc(10, 20) #调用
print(result)
二、函数的参数传递
- 位置实参
根据形参对应的位置进行实参传递
def calc(a, b): # a,b称为形式参数,简称形参,形参的位置实在函数的定义处
print('a=', a)
print('b=', b)
c = a + b
return c
result = calc(10, 20) # 10,20称为实际参数的值,简称实参,实参的位置是函数的调用处
print('sum=', result)
- 关键字实参
根据形参名称进行实参传递
def calc(a, b): # a,b称为形式参数,简称形参,形参的位置实在函数的定义处
print('a=', a)
print('b=', b)
c = a + b
return c
res = calc(b=10, a=20) # 左侧的变量的名称称为 关键字参数,直接将值赋给相应的关键字,类似C语言中的指针。
print('sum=', res)
三、函数的返回值
- 函数参数传递的内存分析
def fun(arg1, arg2): # 函数调用处 形参
print('arg1=', arg1, id(arg1))
print('arg2=', arg2, id(arg2))
arg1 = 100 # 赋值100
arg2.append(10) # 追加10 变量改变之后依然指向原地址,可以理解为地址传递
print('arg1=', arg1, id(arg1))
print('arg2=', arg2, id(arg2))
n1 = 11
n2 = [22, 33, 44] # 列表可变序列
print('n1=', n1, id(n1))
print('n2=', n2, id(n2)) # 输出列表 22,33,44
print('调用函数-----------------------')
fun(n1, n2) # 位置传参 函数定义处 实参
print('结束调用-----------------------')
print('n1=', n1, id(n1)) # n1 是数值型,是不可变的,在函数体的修改不会影响实参的值
print('n2=', n2, id(n2)) # n2 是可变序列,在函数内改变会影响原有列表,所以函数外的列表就会发生改变,
注意看下图中 n1、n2 的id值的改变
在函数调用过程中,进行参数的传递:
**如果是不可变对象,在函数体的修改不会影响实参的值;**不可变对象:tuple string int float bool
如果是可变对象,在函数体的修改会影响到实参的值; 可变对象:list dict set
- 函数定义时,给形参设置默认值,只有与默认值不符的时候才需要传递实参。
def fun(a,b=10):
print(a,b)
fun(100) # 只传一个参数,b采用默认值
fun(20,30) # 位置传参 30将默认值10替换
2、个数可变的位置参数
- 定义函数时,可能无法事先确定传递的位置实参的个数时,使用可变的位置参数
- 使用*定义个数可变的位置形参
- 结果为一个元组
def fun(*args):
print(args)
fun(10)
fun(10, 20, 30)
3、个数可变的关键字形参
- 定义函数时,无法实现确定传递的关键字实参的个数时,使用可变的关键字形参
- 使用**定义个数可变的关键字形参
- 结果为一个字典
def fun(**args):
print(args)
fun(a=10)
fun(a=10, b=20, c=30)
五、变量的作用域
程序代码能访问该变量的区域,根据变量的有效范围可分为
- 局部变量:在函数内定义并使用的变量,只在函数内部有效,局部变量使用global声明
- 全局变量:函数体外定义的变量,可作用与函数内外
def fun(a, b):
c = a + b # c 是局部变量,因为c是在函数体内进行定义的变量, a b 为函数的形参,作用范围也是函数内部,相当于局部变量
print(c)
fun(10, 20)
# print(c) # NameError: name 'c' is not defined
# print(a) # NameError: name 'a' is not defined
name = 'What you really want' # 全局变量
print(name)
def fun():
print(name)
fun()
def fun():
global age # 函数内部定义的变量是局部变量,但当 局部变量使用global声明,这个变量实际上就变成了全局变量。
age = 20
print(age)
fun()
print(age)
六、递归函数
-
递归函数:如果一个函数的函数体内调用了该函数本身,这个函数就成为递归函数。
-
递归的组成部分:递归调用与递归终止条件
-
递归的调用过程:每递归调用一次函数,都会在栈内分配一个栈帧,每执行完一次函数,都释放相应的空间
-
递归的优点:思路和代码简单
-
递归的缺点:占用内存多,效率低下
递归函数,其实c语言明白了,这个就明白了,基本一样的
# 使用递归函数来计算阶乘
def fac(n):
if n == 1:
return 1
else:
return n * fac(n - 1)
print(fac(3))
练习:斐波那契数列(生兔子)
# 斐波那契数列
def fic(n):
if n == 1:
return 1
elif n == 2:
return 1
else:
return fic(n - 1) + fic(n - 2)
print('一共'+str(fic(10))+'只兔子')
for _ in range(1, 10): # 输出一下 每次fic的数值
print(fic(_))
总结
一直坚持下去就好了!
模糊的记得一句话,不要回头看完成了多少,要看还有多少没有完成!
还有73节基础。



