函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。 函数能提高应用的模块性,和代码的重复利用率。你已经知道Python提供了许多内建函数,比如print()。但你也可以自己创建函数,这被叫做用户自定义函数。—摘抄https://www.runoob.com/python/python-functions.html
函数基础
def factory():
print('正在制造手机')
factory()
def shopping():
pass
shopping()

函数各种参数
无参函数
def factory():
print('正在制造手机')
factory()

有参函数
def factory(a,b):
print('a是%s'%a)
print('b是%s'%b)
factory('小明','小王')

实参
指的是在调用函数阶段括号内传入的值,即实参本质就是"值" 调用函数的参数称为实参 形参与实参的关系:在调用函数时,会将实参(值)赋值(绑定)给形参(变量名)
位置传参
factory(3,2)

关键字传参
factory(b=1,a=2)
factory(2,b=2)

默认参数
def factory(a,b=2):
c = a + b
print(c)
factory(1,5)
def register(name,age,sex='男'):
print(name,age,sex)
register('小王',18)
register('小戴',18,'女')
register('小王',18)
register('小王',18)
register('小王',18)

不定长参数
带*参数
可变长度的参数(不定长参数) 在形参中带*:会将调用函数时溢出位置实参保存成元组的形式,然后赋值*后的变量名
def foo(x,y,*z):
print(x,y,z)
print(*z)
foo(1,2,3,4,5,6)
foo(1,*(2,3))
foo(*(1,2,3))
foo(*[1,2,3])
foo(*'abc')

带**参数
在形参中带**:会将调用函数时溢出关键字实参保存成字典的形式,然后赋值**后的变量名
def foo(x,y,**z):
print(x,y,z)
foo(1,2,a=1,b=2,c=3)
foo(1,y=1,a=1,b=2,c=3)

** 与* 混合使用
规范: 在形参中带*与**的,*后的变量名应该为args,**后跟的变量名应该时kwargs
def factory(*args,**kwargs):
print(args)
print(kwargs)
factory(1,2,3,x=3,y=4)
factory(*[1,2,3],**{'x':3,'y':4})

*加在 列表、元组、集合、字典前可以打散元素 **加在字典前可以打散字典成为关键字参数
print(*(1,2,3))
print(*[1,2,3])
print(*{1,2,3})
print(*{'name':'小王','age':18})

函数包装
def bar(x,y,z):
print(x,y,z)
def wrapper(*args,**kwargs):
bar(*args,**kwargs)
wrapper(1,2,3)

多种参数混合
def foo(x,y,*args,m,n,**kwargs):
print(x,y)
print(args)
print(m,n)
print(kwargs)
foo(1,2,3,4,5,6,m=3,n=4,a=1,b=2,c=3)

匿名函数
匿名函数:就是没有名字的函数 为何要用: 用于仅仅临时使用一次的场景,没有重复使用的需求 匿名函数,除了没有名字其他的都有 语法 lambda空格+参数+冒号+函数体代码(表达式或者函数) 一行代码图省事 像java中的lambda表达式
基本用法
print(lambda x,y:x+y)
print((lambda x,y:x+y)(1,2))
print((lambda x,y:print(x+y))(1,2))

巧妙利用匿名函数(简洁、美观、易懂)
对比两种取字典中最大值的方法。匿名函数非常的方便
salaries = {
'xiaowang':3000000,
'xiaodai':10000,
'xiaozhou':3000
}
print(max(salaries))
def func(name):
return salaries[name]
print(max(salaries, key=func))
print(max(salaries, key=lambda name: salaries[name]))
print(min(salaries, key=lambda name:salaries[name]))

nums = [11,33,22,9,1]
res = sorted(nums,reverse=True)
print(res)
for v in salaries.values():
print(v)
print(sorted(salaries.values()))
print(sorted(salaries, key=lambda name: salaries[name], reverse=True))
print(sorted(salaries, key=lambda name: salaries[name], reverse=False))

闭包函数
基本用法
闭包函数 闭指的是:该函数是一个内部函数 包指的是:指的是该内部的函数名字在外部被引用 即调用一个函数,返回的结果是另一个函数还能在调用
print('正在制造手机')
def outer():
print('外面的函数正在运行')
def inner():
print('里面的函数正在运行')
return inner
inner=outer()
inner()

闭包传参
def func(x,y):
print(x+y)
func(1,2)
func(1,2)
def outer(x,y):
def func():
print(x + y)
return func
func=outer(1,2)
func()
func()
闭包函数可以将参数封装好,这样就等于调用的时候不需要在重复指定参数。可以将一些不希望别人修改的参数封装成闭包函数 
装饰器(很重要)
装饰器就是一个特殊的闭包函数 1、什么是装饰器(就是一个函数,只不过这个函数不是给自己使用的,是给其他函数添加功能的) 器指的是工具,而程序中的函数就具备某一功能的工具 装饰指的是为被装饰器对象添加额外功能,例如打印日志、校验参数等等 2、为什么要用装饰器 软件的维护应该遵循开放封闭原则 开放封闭原则指的是: 软件一旦上线运行后对修改源代码是封闭的,对扩展功能的是开放的 这就用到了装饰器 装饰器的实现必须遵循两大原则: 1、不修改被装饰对象的源代码(人的原来的性格,生活方式) 2、不修改被装饰对象的调用方式(人的原来的外貌,名字)
基本用法
name = '小王'
def run(name):
print('=========')
print('我是%s'%name)
print('=========')
return '你好:%s'%(name)
def decorate(func):
def new_func(name):
print('函数执行前的日志 参数: %s'%(name))
res = func(name)
print('函数执行后的日志 返回值: %s'%(res))
return res
return new_func
run=new_func=a=decorate(run)
print(run(name))

通过注解的方式使用装饰器
简化了 run=new_func=decorate(run) 这一步的连续赋值
name = '小王'
@decorate
def run(name):
print('=========')
print('我是%s'%name)
print('=========')
return '你好:%s'%(name)
def decorate(func):
def new_func(name):
print('函数执行前的日志 参数: %s'%(name))
res = func(name)
print('函数执行后的日志 返回值: %s'%(res))
return res
return new_func
print(run(name))

|