意义
1、避免代码冗余
2、提升代码可维护性
3、方便代码重用、使得代码更加模块化
4、分解任务、简化程序逻辑
分类
内建函数
三方函数
自定义函数
使用
#函数定义
def test():
print("hello world")
#函数调用
test() #hello world
参数传递
单一参数
def test(num):
print(pow(num, 2))
test(3) #9
形参:形式上的参数
实参:实际上传递的参数
多个参数
def mysum(num1, num2):
print(num1 + num2)
mysum(1, 2) #3
调用方式 1:直接传递参数,形参和实参必须一一对应
方式2:借助关键字调用,可以不按照顺序
def mysum(num1, num2):
print(num1 + num2)
mysum(num1 = 1,num2 = 3) #4
不定长参数
#方式1
#def 函数名(*args)代表参数是一个元组
def mysum(*t):
sum = 0
print(type(t))#<class 'tuple'>
for i in t:
sum += i
print(sum)
mysum(1, 2, 3, 4, 5)#15
#方式2
#def 函数名(**dict) 用字典接受参数、必须用关键字进行参数传递
def mysum(**kwargs):
print(kwargs, type(kwargs))#{'name': 'sz', 'age': 12} <class 'dict'>
mysum(name = "sz", age = 12)#注意这里key无引号
参数拆包
装包:把传递的参数,包装成一个集合
拆包:把集合参数,再次分解成单独的个体
def test(**kwargs):
print(kwargs) #test(a = "1", b = "2")
mySum(**kwargs) #1 2 相当于mySum(a = "1", b = "2")
def mySum(a, b):
print(a)
print(b)
test(a = "1", b = "2")#要和形参一致
def mySum(a, b, c, d):
print(a + b + c + d)
def test(*args):#args一般代表多个参数的意思
print(args) #(1, 2, 3, 4)
#拆包
print(*args)#1 2 3 4
mySum(*args)#10
test(1, 2, 3, 4)
缺省参数
如果某个数据是一个固定值,或者属于主功能之外的小功能实现
则可以使用默认值,这种参数称为“缺省参数”
def test(num = 19):
print(num)
test() #19
test(100)#100
值传递和引用传递
值传递:只传递过来数值,是一个数据的副本,会在地址里面重新开辟一个空间,把值复制在里面,然后,把地址(id)传给形参。
引用传递:通过地址,可以操作同一份原件
python里面只有引用传递
如果数据类型是可变类型,可以改变原件
如果数据类型是不可变类型,不能改变原件
def change(num):
print(num, id(num)) #10 2132131408464
b = 10
print(id(b))#2132131408464
change(b)
def change(num):
print(num, id(num)) #10 2132131408464
num = 666
print(num) #重新开辟空间存666 再改变num的指针
b = 10
print(id(b))#2132131408464
change(b)
print(b)
返回值
def mySum(a, b):
return a + b, a - b #return后的语句不会被执行
result1, result2 = mySum(1,5)
print(result1, result2) #6 -4
只能返回一次
如果想返回多个数据,可以将多个数据包装成一个整体(字典、元组、列表...),整体返回。
函数的使用描述
1、使用原因:当我们编写第三方函数,为了方便他人使用,就需要描述清楚我们所写的函数功能和方式
2、def 函数():''' 描述帮助信息'''
3、查看函数使用文档:help(函数)
一般函数的描述,需要说明:函数的功能、参数的含义、参数的类型、参数是否可以省略、参数默认值、返回值的含义、返回值的类型。
def mySum(a, b = 2):
'''
计算俩个数据的和和差
:param a:数值1,数值类型,不可选,无默认值
:param b:数值2,数值类型,可选,默认为2
:return:返回的是计算的结果,和 差
'''
return a + b, a - b #return后的语句不会被执行
help(mySum)
常用高级函数
偏函数
当我们写一个参数较多的函数时,如果有些参数大部分场景下都是一个值,为了简化使用,可以创建一个新函数,指定我们所使用的函数的某个参数为某个固定的值,这个新函数就被称为“偏函数”。
def test(a, b, c, d = 1):
print(a + b + c + d)
def test1(a, b, c, d = 2):
test(a, b, c, d)
test1(1, 2, 3) #8
import functools
test2 = functools.partial(test, c = 5) #第一个参数是函数名,第二个参数是默认值,返回对应的偏函数
print(test2, type(test2))
test2(1,2) #9
使用场景
numStr = "10010"
result = int(numStr, base = 2)#base是指的把原来的数据当作几进制来进行转换
print(result) #18
import functools
int2 = functools.partial(int, base = 2)
print(int2(numStr))#18
高阶函数
函数本身也可以作为数据传递给另外的变量
def test(a, b):
print(a + b)
test1 = test
test(1, 2) # 3
test1(1, 2) # 3
当一个函数A的参数,接受的又是另外一个函数时候,可以把A当作是高阶函数,例如sorted函数
key = functioname
def caculate(num1, num2, calculateFunc):
print(calculateFunc(num1, num2))
def mySum(a, b):
return a + b
def subfun(a, b):
return a - b
caculate(1, 5, mySum) #6
caculate(1, 5, subfun) #
返回函数
指的是一个函数内部,其返回的数据是另外一个函数,把这样的操作称为“返回函数”
def getFunc(flag):
def sum(a, b, c):
return a + b + c
def sub(a, b, c):
return a - b - c
if flag == "+" :
return sum
else:
return sub
print(getFunc("+"), type(getFunc("+")))
#<function getFunc.<locals>.sum at 0x00000237066103A0> <class 'function'>
print(getFunc("+")(1, 2, 3)) #6
匿名函数
也就是 lambda函数
没有名字的函数
只能写一个表达式,不能直接return
表达式的结果就是返回值
所以,只适用于一些简单的操作处理
#lambda 参数1,参数2 : 表达式
#表达式的结果就是返回值
result = (lambda x, y : x + y)(1, 2)
print(result) #3
func = lambda x, y : x + y
print(func(4, 2)) #6
l = [{"name": "1", "age": 18}, {"name": "2", "age": 17}, {"name": "3", "age": 19}]
result = sorted(l, key = (lambda x : x["age"]))
print(result) #[{'name': '2', 'age': 17}, {'name': '1', 'age': 18}, {'name': '3', 'age': 19}]
闭包
在函数嵌套的前提下
内层函数引用了外层函数的变量(包括参数
外层函数,又把内层函数当作返回值进行返回
则 内层函数+所引用的外层变量,称作“闭包”
def test():
a = 10
def test1():
print(a)
b = 10
print(a + b)
return test1
fun = test()
fun() #10 20
功能:外层函数,根据不同的参数,来生成不同作用功能的函数。
def line_config(content, length):
def line():
print("-" * (length//2), content, "-"*(length - (length//2)))
return line
line1 = line_config("abc", 20)
line2 = line_config(123, 20)
line1() #---------- abc ----------
line2() #---------- 123 ----------
闭包注意事项
1、闭包中,如果要修改引用的外部变量,必须使用nonlocal来申明,否则会在闭包内新定义变量。
def test():
num = 10
def test2():
nonlocal num
num = 20
print(num, id(num))
print("original {} {}".format(num,id(num))) #original 10 2435248515664
test2() #20 2435248515984
print("original {} {}".format(num,id(num))) #original 20 2435248515984
return test2
test()
2、闭包内引用了一个后期会发生变化的变量时候,一定要注意
def test():
a = 1
def test1():
print(a)
a = 2
return test1
fun = test()
fun()# 2 只有执行到函数内部时候才会去找内部标识所对应的值
def test():
funcs = []
for i in range(4):
def test1():
print(i)
funcs.append(test1)
return funcs
fun = test()
fun[0](), fun[1](), fun[2](), fun[3]() #3 3 3 3