```python
```python
一.什么是函数:
--相当于具备某一功能的工具;先定义,在调用
二.函数的作用:
--2.1.使代码结构化,具有较高的可读性
--2.2.实现的复用
--2.3.易维护,易扩展
三.函数的定义:
--3.1.将函数体代码保存到内存空间
--3.2.将上述内存地址赋值给函数名
--3.3.定义函数不会执行函数体代码,但会检测函数体语法
--3.4.函数类型:
--3.4.1.无参函数
--3.4.2.有参函数
--3.4.3.空函数
四.调用函数:
--4.1.语句形式:只调用函数,不做任何操作
--4.2.表达式形式:
--4.2.1.数学表达式
--4.2.2.赋值表达式
--4.`3在这里插入代码片`3.将函数当作参数调用
五. 函数返回值
--5.1.return是函数结束的标志,终止函数的运行,并将return后的值当作本次运行的结果返回
--5.2.情景:
--5.2.1. None:函数内没有return或者return一个空值
--5.2.2. 返回一个值,return后跟一个值
--5.2.3. 返回多个值,return后跟多个值(用逗号分隔开),返回一个元组
六. 参数的使用
--6.1. 形参与实参
--6.1.1. 形参:在函数定义阶段的参数,简称形参
--6.1.2. 实参:在函数调用阶段传入函数的参数,简称实参
--形式1. 直接传入具体的值
--形式2. 定义变量,传入变量名
--形式三. 以函数作为参数,传入
--6.1.3. 两者的关系:在函数调用阶段,实参的值会赋值给形参,这种绑定关系只能在函数体内用,函数体外会报错
--6.2. 位置参数
--6.2.1 位置形参(在函数定义阶段)
--按照从左到右的顺序直接定义的变量名(必须要传入值)
--6.2.2 位置实参(在函数调用阶段)
--按照形参位置一一传值,顺序不可变,数据类型必须一致
--6.3. 关键字参数(只针对实参)
--6.3.1. 关键字实参:在函数调用阶段按照key=value的形式传参
--6.3.2 特点:指定给哪个参数传值,忽略形参顺序
--6.4. 位置实参和关键字实参混合使用:
--6.4.1. 位置实参必须放在关键字实参之前
--6.4.2. 不能为同一个形参重复传值
--6.5. 默认形参
--6.5.1 在函数定义函数阶段就已经复制的参数,在函数调用阶段可以不用传值,若在调用阶段传值,则使用新传入的值
--6.5.2 位置形参必须在默认形参的左边
--6.6. 可变长度参数
--6.6.1 可变长度指的是再调用函数时,传入的实参个数不固定,针对溢出的实参必须有对应的形参来接收
--6.6.2 可变长度的位置参数
-- *形参名 用来接收溢出的位置实参,溢出的位置实参会被*保存成元组的格式,然后赋值给紧跟其后的形参名
def func(x,y,*args):
print(x,y,z)
func(1,2,3,4,5,6)
用途:
def sum_num(*args):
result = 0
for i in args:
result += i
return result
res = sum_num(1,2,3,4,5,6,6,9,8,7)
-- **形参名 用来接收溢出的关键字实参,溢出的关键字实参会被保存成字典格式然后赋值给紧跟其后的形参名
def func(x,y,**kwargs):
print(x,y,kwargs)
func(x=1,y=2,m=3,n=4,p=5,q=6)
--6.6.3 *在实参中的应用
--实参中带*,先将*后的值拆分成位置实参
--举例:
def func(x,y,z):
print(x,y,z)
func(*[1,2,4]) ======>func(1,2,4)
--形参与实参中都带*:
--举例:
def func(x,y,*args):
print(x,y,z)
func(1,2,*[3,4,5,6])
--实参中带**,先将*后的值拆分成位置实参
--举例:
def func(x,y,**kwargs):
print(x,y,kwargs)
func(x=1,y=2,a=1,b=2,c=3) ======>kwargs=(1,2,{'a':1,'b':2,'c:3'})
--形参与实参中都带**:
--举例:
def func(x,y,**kwargs):
print(x,y,kwargs)
func(x=1,y=2,**{'a':1,'b':2,'c:3'}) ====> kwargs = (x=1,y=2,a=1,b=2,c=3)
--`*`与`**`混用:
--注意:*args对应位置参数,**kwargs对应关键字参数
def func(x,y,*args,**kwargs):
print(x,y,args,kwargs)
func(1,2,3,4,5,6,7,a=1,b=2,c=3) ====>args = (3,4,5,6,7), kwargs={'a':1,'b':2,'c:3'}
6.7 命名关键字参数:
--在定义函数时,`*`后面定义的参数,称之为命名关键参数
def func(x,y,`*`,a,b): ====>a,b称为命名关键字参数
pass
--特点:
命名关键字参数必须按照key=value的形式传值
可以为命名关键字参数设置默认值
--用途:
强制使用关键字传值的形式
6.8 参数及其组合使用的顺序:
--形参: 位置形参,默认值形参,*args,命名关键字形参,**kwargs
--实参:位置实参在关键字实参的左边
七. 名称空间
7.1 什么是名称空间: 存放名字的地方
7.2 分类:
1.内置名称空间:
--存放的名字:python解释器内置的名字
--存货周期:python解释器启动则产生,python解释器关闭则销毁
2.全局名称空间:
--存放的名字:运行顶级代码产生的名字,即不是内置,也不是函数内定义的名字
顶级代码:{x = 10
if x > 0:
z=1}
函数内定义:{def func(x,y):
x = 1
y = 2}
--存活周期:python文件执行时产生,执行完毕后销毁
3.局部名称空间:
--存放的名字:在调用函数时,运行函数体代码过程中产生的函数内的名字
--存活周期:调用函数时产生,函数调用完毕销毁
4.名称空间的加载和销毁顺序:
--局部命名空间 > 全局命名空间 > 内置命名空间
5.名称空间的查找顺序:当前所在的位置向上一层一层的查找
6.命名空间的嵌套关系是以函数定义阶段为准,与调用位置无关
x = 1
def func():
print(x)
def foo():
X=2
func()
foo() =====>输出结果为1
八. 作用域
1. 全局作用域:内置命名空间,全局命名空间
--全局存活 全局有效 被所有函数共享
2. 局部作用域:局部命名空间
--临时存活 局部有效
3. 将局部变量申明为全局变量:global
4. 修改外层函数包含的名字对应的值(不可变类型)
5.函数对象:可以把函数当成变量去用
--可以赋值
--把函数当作参数传给另外一个函数
--把函数当作另外一个函数的返回值
--可以当作容器类型的一个元素
--举例:
def quit():
print("退出")
def register():
print("注册")
def login():
print("登录")
def search():
print("查询")
def transfer():
print("转账")
def withdraw():
print("提现")
dictionary = {'0':quit,
'1':register,
'2':login,
'3':search,
'4':transfer,
'5':withdraw}
while True:
print('''
'0' 退出 '1' 注册 '2' 登录 '3' 查询 '4' 转账 '5' 提现
''')
choice = input("请输入命令编号:").strip()
if choice == '0':
break
if not choice.isdigit():
print("必须输入编号")
else:
if choice in dictionary:
dictionary[choice]()
6.函数嵌套:
嵌套调用:再调用一个函数的同时又调用其他函数
def max1(x, y):
if x > y:
return x
else:
return y
def max2(a,b,c,d):
res = max1(a,b)
res2 = max1(res,c)
res3 = max1(res2,d)
return res3
print(max2(1,3,4,5))
嵌套定义:在函数内定义函数
def func():
def func1():
pass
def func2():
pass
def func3():
pass
func1()
func2()
func3()
func()
7. 闭包函数:
闭函数:指的是该函数是定义在一个函数内的函数
包函数:该函数包含对外层函数作用域名字的引用:
def f1():
x = 13
def f2():
print("f2:",x)
return f2
f = f1()
f()
def func():
x = 2222
f()
func()
九. 补充:三元运算符
def func(x, y):
if x > y :
return x
else:
return y
print(func(1,2))
x = 2
y = 1
print(x if x>y else y)
总结:条件成立时要返回的值 if 条件 else 条件不成立时要返回的值
十. 函数的递归调用:是函数嵌套调用的一种特殊形式,具体是指在一个函数的调用过程中又直接或间接的调用了本身
直接调用(就是一个死循环):
def f1():
print('这是我f1的函数体')
f1()
f1()
间接调用
def f1():
print('我是f1')
f2()
def f2():
print('我是f2')
f1()
f1()
总结:递归的本质就是循环,即用函数的形式重复运行一段代码,所以必须要在满足某一条件的时候结束递归调用。
def func(n):
if n == 10:
return
else:
print(n)
n += 1
func(n)
func(0)
递归调用的两个阶段:
(1)回溯:一层一层的调用下去
def f1():
print('这是我f1的函数体')
f1()
f1()
(2)递推:满足某种结束条件,结束递归调用,然后一层一层返回
递归的应用:
lis = [1, [2, [3, [4, [5, [6, [7, [8, [9, [10]]]]]]]]]]
print(len(lis))
def func(lis_):
for x in lis_:
if type(x) == list:
func(x)
else:
print(x)
func(lis)
十一. 匿名函数lambda
1. 有名函数:func=函数的内存地址
def func(x, y):
return x + y
2. 匿名函数
定义:lambda 参数 : 表达式
print((lambda x, y: print(x + y)))
调用函数:
方式一:(lambda x, y: print(x + y))(1, 3)
方式二:func = lambda x, y: print(x + y)
res = func(1,2)
使用场景:调用一次,然后销毁,与其他函数配合使用
salaries = {
'爱丽丝': 456456,
'漆仲勇': 45645666,
'乔峰': 564412,
'段誉': 454544,
'虚竹': 45212,
'王语嫣': 45411
}
res = max(salaries,key=lambda k: salaries[k])
print(res)
salaries = {
'爱丽丝': 456456,
'约翰': 45645666,
'乔峰': 564412,
'段誉': 454544,
'虚竹': 45212,
'王语嫣': 45411
}
res = sorted(salaries, key=lambda k:salaries[k])
print(res)
lis = ['alex', 'lxxx', 'wxxx', 'xxla']
res = map(lambda name: name+'dsb', lis)
print(res)
lis = ['alex_sb', 'lxix_sb', 'wxx_sb', 'xxla']
res = map(lambda name: name.endswith('sb'), lis)
print(res)
from functools import reduce
lis = [1, 2, 3, 4, 5, 6]
res = reduce(lambda x, y: x + y, lis,2)
print(res)
十二. 函数的类型提示
可以在参数后添加传入参数提示信息,写入的数据类型不限
def register(name:str, age:int, hobbies:tuple):
print(name, age, hobbies)
register('didj', 45, ('dkj',))
查看提示信息:func.__annotations__