目录
3.匿名函数只能有一个表达式,有自己的命名空间,不用再写return语句,表达式的结果就是其返回值
将一个大型程序按照功能分隔成若干个小型模块
1. 模块相对独立,功能单一、结果清晰、接口简单(内聚、耦合)
2. 减少程序的复杂性
3. 提高元器件的可靠性
4. 缩短软件开发周期
5.避免程序开发的重复劳动
- def 函数名(形参列表):#函数首部
- 内部功能代码 # 函数体
- return 表达式
函数名区分其他函数作用,本质是该函数在内存所占空间的首地址,是一个常量,命令要求见名知意
作用 --- 函数接收数据的变量空间
原则 --- 调用函数的时候,形参变量会分配空间,调用结束后释放空间
设计 --- 形参名称、个数,多个参数使用逗号分隔
编写程序实现函数功能
- def summer(lis):
- '''这里写函数的说明文档,
- :param lis : 参数列表说明,
- :return:返回值说明
- '''
- t = 0
- for i in lis:
- t += i
- return t
- summer()
使用函数功能,传递参数
函数名 ( 实参列表 )
- fun(m) # 调用fun函数,将实参m传递给形参
- n = fun(m) # 调用fun函数,返回值赋值给n变量
- s = s*fun(m) # 调用fun函数,返回值参与后续运算
- fun() # 无返回值、无参,只是执行一次
例 计算C(m,n) = m! / (n! * (m-n)!)
- # 例 计算C(m,n) = m! / (n! * (m-n)!)
- def fun(x):
- '''
- :param x: 需要进行阶乘的参数
- :return: 返回X的阶乘
- '''
- funx = 1
- for i in range(1, x + 1):
- funx = funx * i
- return funx
-
-
- m = int(input("请输入m的值:"))
- n = int(input("请输入n的值:"))
- C = fun(m) / (fun(n) * fun(m - n))
- print('结果:', C)
-
- 结果:
- 请输入m的值:5
- 请输入n的值:2
- 结果: 10.0
-
表示函数执行到此结束,返回其后的对象,函数执行到此结束,若无返回值,省略return语句,会返回None
一旦函数执行过程中遇到return语句,之后的函数体代码都不会执行,会跳出函数体
- def func():
- pass
- return # 此时,后边的代码都不会执行
- print()
- pass
不许参数、必备参数,必须按照正确的顺序传到函数中,实参和形参按位置对齐,个数相同
- def fun(str1, str2): # 形参
- print(str1, str2)
-
-
- fun('hello', 'world') # 实参
使用形参的名字来确定输入的参数值,实参不再需要与形参的位置完全一直
- def fun(str1, str2): # 形参
- print(str1, str2)
-
-
- fun(str2='hello', str1='world') # 实参
调用参数时,如果没有传递参数,会默认使用默认阐述
- def fun(str1, str2): # 形参
- print(str1, str2)
-
-
- fun('hello') # 实参
注意 :
默认参数必须写到形参列表的最右边,否则报错
默认参数尽量不要指向不变的对象
例 国内上市某互联网公司的Python面试题:
def func(a=[]): a.append('A') return a print(func()) print(func()) print(func()) 结果: ['A'] ['A', 'A'] ['A', 'A', 'A'] 而不是: ['A'] ['A'] ['A'] #原因:函数体装入内存后,a列表会被创建,内存中有a列表内容,伴随着每一次调用a列表都不会清空回收,会继续使用直到程序结束 def func(a=[]): print('函数内部a的地址为:%s' % id(a)) a.append('A') return a b = print(func()) print('b的地址为:%s' % id(b)) print(b) c = print(func()) print('c的地址为:%s' % id(c)) print(c) d = print(func()) print('d的地址为:%s' % id(d)) print(d) 结果: 函数内部a的地址为:2915279324672 ['A'] b的地址为:140722425179352 None 函数内部a的地址为:2915279324672 ['A', 'A'] c的地址为:140722425179352 None 函数内部a的地址为:2915279324672 ['A', 'A', 'A'] d的地址为:140722425179352 None需要输出结果为 --- 使用不变的类型作为默认值修改
['A'] ['A'] ['A']
def func(a=None): if a is None: a = [] a.append('A') return a print(func()) print(func()) print(func()) 结果: ['A'] ['A'] ['A']
定义 --- 传入的参数可以是任意多个
格式1 --- * 形参,增加一个星号,可以接受多个参数并存储到元组中
例
- def func(str1, *str2):
- print(str1, str2)
-
-
- func('hello', 'world', 'china', '123456')
-
- 结果:
- hello ('world', 'china', '123456')
格式2 --- ** 参数,增加两个星号,以关键字参数形式传递,以字典形式存储
例
- def func(str1, **str2):
- print(str1, str2)
-
-
- func('hello', a='world', b='china', c='123456')
-
- 结果:
- hello {'a': 'world', 'b': 'china', 'c': '123456'}
注意:
若形参列表中只有单独的星号,则对实参必须以关键字参数形式传入
def func(str1, *,str2): print(str1, str2) func('hello', str2='world') 结果: hello world
作用域指变量的有效范围,决定访问权限
块级、函数、类、模块、包(由小到大),Python没有块级 等同于普通语句
层 | 作用 |
---|---|
L(local) | 局部 |
E(enclosing) | 闭包函数外的函数中 |
G(global) | 全局 |
B(built-in) | 内建 |
- x = int(2, 9) # 内建作用域
-
- global_bar = 0 # 全局作用域
-
-
- def outer():
- out_ver = 1 # 闭包函数外的函数中
-
- def inner():
- in_var = 2 # 局部作用域
L -> E -> G -> B的顺序查找变量,即在局部找不到变量则回到局部外去找,再找不到则到全局去找,最后到内建去找变量,若还找不到则报错
定义在函数内部的称为局部变量,定义在函数外的变量全局的作用域,称为全局变量
- a = 1 # 全局变量
-
-
- def func():
- b = 2 # 局部变量
- print(a)
-
- def inner():
- c = 3 # 更局部的变量
- print(a)
- print(b) # b外部变量
- print(c)
-
-
- func()
-
- 结果:
- 1
- total = 0 # 全局变量
-
-
- def plus(arg1, arg2):
- total = arg1 + arg2
- print('函数内局部变量total =', total)
- print('函数内局部变量total地址为:%s' % id(total))
- return total
-
-
- plus(10, 20)
- print('函数外的全局变量total=', total)
- print('函数外的全局变量total地址为:%s' % id(total))
-
- 结果:
- 函数内局部变量total = 30
- 函数内局部变量total地址为:3010629299408
- 函数外的全局变量total= 0
- 函数外的全局变量total地址为:3010629298448
- total = 0 # 全局变量
-
-
- def plus(arg1, arg2):
- global total # 使用global声明此处total引用外部的total
- total = arg1 + arg2
- print('函数内局部变量total =', total)
- print('函数内局部变量total地址为:%s' % id(total))
- return total
-
-
- plus(10, 20)
- print('函数外的全局变量total=', total)
- print('函数外的全局变量total地址为:%s' % id(total))
-
- 结果:
- 函数内局部变量total = 30
- 函数内局部变量total地址为:2221631892688
- 函数外的全局变量total= 30
- 函数外的全局变量total地址为:2221631892688
- a = 10
-
-
- def test():
- a += 1
- print(a)
-
-
- test()
- #执行会报错,a += 1 相当于a = a+1 所覆盖,Python规定如果函数内部需要修改一个变量,那么该变量为内部变量,除非使用global声明
-
- #应修改为下列结果
- a = 10
-
-
- def test():
- global a # 声明使用外部变量
- a += 1
- print(a)
-
-
- test()
- a = 1
- print('全局变量a的地址:', id(a))
-
-
- def fun():
- a = 2
- print('函数fun内部a的地址为:', id(a))
-
- def inner():
- nonlocal a
- a = 3
- print('函数inner调用后闭包内部变量a的地址:', id(a))
-
- inner()
- print('函数 inner低啊用后,闭包外部的a的地址:', id(a))
-
-
- fun()
-
- 结果:
- 全局变量a的地址: 2248198875440
- 函数fun内部a的地址为: 2248198875472
- 函数inner调用后闭包内部变量a的地址: 2248198875504
- 函数 inner低啊用后,闭包外部的a的地址: 2248198875504
一个函数在它的函数内部调用自身称为递归调用
- def fun(n):
- if n == 0:
- return 0
- else:
- if n > 1:
- x = fun(n - 1) * n
- else:
- x = 1
- return x
-
-
- m = int(input('请输入一个正整数:'))
- print('阶乘的结果为:', fun(m))
-
- 结果:
- 请输入一个正整数:30
- 阶乘的结果为: 265252859812191058636308480000000
1.每一次递归,整体问题的值都要比原来的要小,并且低轨道一定层次后必须给出结果。
2.为了防止递归的无休止调用,必须在函数内部有终止递归的手段,一般配合if-else语句
3.递归需要注意防止递归深度溢出,在Python中使用栈这种数据结构实现的,默认的深度为1000层,超出该深度会抛出异常,每当进入下一个递归时,栈会增加一层,当函数每返回一次。栈会减少一层
4.递归可以使用程序变得简洁,增加程序可读性,但每次递归都要重新开辟内存空间
当创建函数时有时不需要显式的定义函数,直接省略函数名传入参数计算即可,省略函数的命名,通过水平不发生表达式实现函数
所谓匿名即不再使用def关键字来创建函数
lambda --- 只是一个表达式,不是一个代码块,函数体比def定义的函数简单
lambda --- 只能封装有限的逻辑语句
lambda 参数 : 表达式
- lambda x: x * x
-
-
- # 相当于
- def fun(x):
- return x * x
lambda 势函数关键字
lambda之后的x为函数参数,相当于原先的形参
x*x为执行代码