python - 函数
目录
函数的定义与调用
1.什么是函数
在数学·里面·函数是一个表达式的集合
例如 : f(x) = x +10
在开发语言里面:
函数是指具体实现某一功能的代码
函数定义:用关键字def
def add(a, b):
print("exac add function")
return a + b
print(add(1, 2))
result = add(3, 4)
print(result)
#为什么要写函数:
#1.方便维护,模块化设计
以上代码为例,如果没有封装add函数,那么当代码出错的·时候我们需要到两个地方进行排查,但是封装函数以后,我们只需要检查add函数。
#2.减少代码的冗余
#函数的参数
1.形参:形式参数,函数定义时,指定的参数。
以上面的add函数为例:形参就是 add(a,b)
2.实参:实际线束,函数调用的术后,传递的参数。
以上面的add函数为例,实参就是 add(1,2)
#按形参来分:
1.必选参数
2.默认参数
3.可变长位置参数
4.可变长关键字参数
#按实参来分
1.位置参数
2.关键字参数
# 必选参数
def stuinfo(name, age, sex):
print(f"myname is {name}, myage is {age}, mysex is {sex}")
# 有几个必选参数就要传入几个参数。参数的位置是一一对应的
# 少传或者多传会报错。
stuinfo("sc", 4, 'man')
# 默认参数
def stuinfo(name, age, sex='man'):
print(f"myname is {name}, myage is {age}, mysex is {sex}")
stuinfo("sc", 21)
stuinfo("sc", 21, 'women')
# 关键字参数
stuinfo("sc", sex='man', age=6)
# 位置参数一定要放在关键字参数的前面。
#注意定义顺序,默认参数放在必须参数前面
#注意调用顺序,关键字参数必须放在位置参数的后面
# 可变长位置参数
def myargs(name, *num):
print(f"{name}:{num}")
print(type(num), *num)
myargs("sc")
myargs("sc1", 1)
myargs("sc2", 1, 2)
# packing and unpacking
# packing
# 1,2-->打包为元组(1,2)
# *num
# unpacking --》{"a":1,"b":2} --》a=1,b=2
# (1,2)--》1,2
# 可变长位置参数 --》 传进来的参数打包成元组。
def sum1(*args):
sum0 = 0
for i in args:
sum0 += i
print(f"可变长位置参数的和为{sum0}")
# 可变长关键字参数 --》 穿进来的参数打包成字典。
#
def sum2(**kwargs):
sum3 = 0
for i, j in kwargs.items():
sum3 += j
print(f"可变长关键字参数和为:{sum3}")
sum1(1, 2, 3, 4, 5, 6, 7)
sum2(a=1, b=2, c=3, d=4)
# 形参定义顺序
# func01(必选参数,可变长位置参数,默认参数,可变长关键字参数。)
# 实参
# func01(位置参数,关键字参数)
#函数的return语句
#一个函数一旦执行到return就退出,不会执行后面的语句
#如果函数没有return,默认返回None,
#如果return后面不接表达式,返回值也是None。
#return 一次也可以返回多个值。
def maxnum(x, y):
print("return 语句:...")
if x > y:
print("return x")
return x
elif x < y:
print("return y")
return y
else:
print("return end ..")
return x, y
result = maxnum(8, 8)
print(f"结果为:{result}")
# 匿名函数 -lambda
匿名函数及其表达式
匿名函数在创建时不需要命名,所以叫匿名函数
匿名函数有个限制,就是只能有一个表达式,不用写retutrn
返回值就是改函数的值
# 使用匿名函数来返回两个数之间的最大值
maxnum = lambda a, b: max(a, b)
maxnum1 = lambda a, b: a if a > b else b
maxnum2 = lambda a, b: a > b and a or b
print(maxnum(100, 200))
print(maxnum1(100, 800))
print(maxnum2(100, 2800))
# 使用匿名函数,将传入的浮点数保留两位小数
# round 将一个数保留几位小数输出成一个浮点数
floatnum = lambda x: round(x, 2)
floatnum1 = lambda x: float('%.2f'%x)
print(floatnum(2.168454))
print(floatnum1(2.168454))
E:\python\python3.9.1\python.exe E:/tlbb/python函数/匿名函数和递归函数.py
200
800
2800
2.17
2.17
# 递归函数
# 自己调用自己,形成循环
# 定义出口条件,什么时候结束递归
# 通常是把一个大问题通过寻找规律可以缩小规模时候使用
# 不能无限制的递归,最大深度996
#递归是非常耗内存的,它会把每一次的中间结果保存在内存中,直到找到出口
#能不用递归尽量不用递归,因为它计算量大,耗内存,效率低
例:
求取n的阶乘
f(n)=1*2*3*..*n
f(n)=n*f(n-1)
# 求取 n 的阶乘、
# f(n)=1*2*3*....*n
# 最大递归深度 996
def func01(n):
if n == 1:
return 1
return n * func01(n-1)
print(func01(5))
E:\python\python3.9.1\python.exe E:/tlbb/python函数/匿名函数和递归函数.py
120
Process finished with exit code 0
使用递归求取斐波拉契数列
# 1,1,2,3,5,8,13,21
# 使用递归实现斐波拉契数列
# 1,1,2,3,5,8,13
def fblq(n):
if n == 1 or n ==2:
return 1
else:
return fblq(n-1)+fblq(n-2)
num = int(input("请输入一个数:"))
for i in range(1, num+1):
print(fblq(i), end=',')
E:\python\python3.9.1\python.exe E:/tlbb/python函数/匿名函数和递归函数.py
请输入一个数:8
1,1,2,3,5,8,13,21,
Process finished with exit code 0
雌雄兔子的繁殖问题
有一对雌雄兔子,没两个月就繁殖雌雄兔一对,问n个月后有多少对兔子
f(n)=f(n-2)*2
def rabbits(n):
if n == 1 or n == 2:
return 1
else:
return rabbits(n-2) * 2
print(rabbits(6))
E:\python\python3.9.1\python.exe E:/tlbb/python函数/匿名函数和递归函数.py
4
Process finished with exit code 0
函数的参数传递
本质上面都是传递引用
全局变量和局部变量
函数的参数传递本质上面都是传递引用
变量的空间作用域
def func1(x):
print(x)
# 定义在函数内部的称为局部变量
x = 100
# 改变局部变量的值全局变量的值不会变
print(x)
# 全局变量
x = 1
但是对于可变数据类型来说,改变它的值全局变量也会改变
例如,对一个可变数据类型 : 列表来说;
# 可变数据类型
def f(x):
x[0] = 100
print(x)
a = [1, 2, 3]
f(a)
print(a)
E:\python\python3.9.1\python.exe E:/tlbb/python函数/03.函数的参数传递.py
[100, 2, 3]
[100, 2, 3]
Process finished with exit code 0
# 参数定义的时候。默认参数避免定义成可变数据类型
例如:
可以看到,我们列表a因为是一个可变数据类型,所以每一次追加
1的时候,a也会变,所以就不是我们刚定义时候的空列表了
# 参数定义的时候,默认参数避免定义成一个可变数据类型
def f(a=[]):
a.append(1)
print(a)
f()
f()
f()
E:\python\python3.9.1\python.exe E:/tlbb/python函数/03.函数的参数传递.py
[1]
[1, 1]
[1, 1, 1]
Process finished with exit code 0
# 变量的作用域
如果要声明一个变量为全局变量,就不要在前面再定义一个同名的局部变量,因为会产生混淆,会报错。
# 在局部变量里面修改全局变量的值
def f():
global x #申明x为全局变量
x = 5
x = 1
f()
print(x)
E:\python\python3.9.1\python.exe E:/tlbb/python函数/03.函数的参数传递.py
5
Process finished with exit code 0
# 变量名的解析(LEGB)
1.在本地变量中·找 --》local
2.在任意上层函数中找 --》 enclosing
3.在全局变量中找 --》 global
4.在内置作用域找 --》 builtin
以双下滑线和双下滑线结尾的变量都是内置变量
例如 : 当前输出 : 3
def f():
x = 2
def f2():
x = 3
print(x)
f2()
x = 1
f()
E:\python\python3.9.1\python.exe E:/tlbb/python函数/03.函数的参数传递.py
3
Process finished with exit code 0
将x = 3注释掉以后:
输出 : 2
E:\python\python3.9.1\python.exe E:/tlbb/python函数/03.函数的参数传递.py
2
Process finished with exit code 0
将x = 2注释掉以后:输出: 1
E:\python\python3.9.1\python.exe E:/tlbb/python函数/03.函数的参数传递.py
1
Process finished with exit code 0
# 文档注释 (Document String)
不管什么时候,注释是很重要的,
def f():
"""
this is test func
:return:
"""
print("hello")
print(help(f))
E:\python\python3.9.1\python.exe E:/tlbb/python函数/03.函数的参数传递.py
Help on function f in module __main__:
f()
this is test func
:return:
None
Process finished with exit code 0
# 内建函数和工厂函数
内建函数:
python 里面已经建好的,我们无需导入,直接调用就好
内建方法:
一般是针对面向对象而言,是类的方法。
内建方法就是指一个自带的对象所带的方法,例如list的pop方法
工厂函数:
所谓工厂函数就是指这些内建函数都是类对象
他们看上去像函数,实质上他们是类
当你调用他们的时,实际上是生成了该类型的一个实例,就像工 厂生产货物一样。
工厂函数主要与数据类型相关
int(),float(),complex(),bool()
str(),
list(),tuple()。生成列表或者元组
dict(),set(),生成一个字典或者集合。
slice()
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通