1. 匿名函数
语法: lambda [arg1 [,arg2,.......argn]]:expression 注意点: arg1:参数名,可以带多个,参数名之间都逗号隔开 expression : 表达式(数字和运算符组成的),只能有一个 匿名函数会自动将表达式的结果返回,返回的结果可以用变量来接受, 也可以直接用print()输出 调用匿名函数:变量名(参数值)
# 案例:输入任意一个数字,要求返回该数字的平方,用函数方式来实现。
# 普通函数实现
def fun1(m): # 函数名
return m * m
print(fun1(2))
def fun1(m): # 函数名
return m + m
print(fun1(3)) # 6
# 匿名函数实现
res = lambda m : m * m
# 调用匿名函数
print(res(4))
# 匿名函数实现
add = lambda m,n : n + m
# 调用匿名函数
print(add(4,10))
2. 匿名函数+内置函数的使用
max() 求最大值 min() 求最小值 sum() 求和
# 使用匿名函数求列表[10,20,30]中所有元素的和,列表中的最大值及列表中的最小值
lst = [10,20,30]
print(max(lst))
print(min(lst))
print(sum(lst))
max_res = lambda x : max(x)
print(max_res(lst))
min_res = lambda x : min(x)
print(min_res(lst))
sum_res = lambda x : sum(x)
print(sum_res(lst))
filter+匿名函数 filter(function, iterable)
# 案例:已知一个列表为[1,4,6,9,12,23,25,28,36,38,41,56,63,77,88,99],找出元素值为偶数的数据,并存放在列表当中。
lst = [1,4,6,9,12,23,25,28,36,38,41,56,63,77,88,99]
# 方式一:用普通函数找出元素值为偶数的数据
new_lst = []
def isodd(m):
# print(m)
if m % 2 == 0:
print(m)
# new_lst.append(m)
for i in lst:
isodd(i)
print(new_lst)
def isodd(m):
# print(m)
if m % 2 == 0:
return m
print(list(filter(isodd, lst))) #列表:print(list(range(1,10)))
注意点:在filter的function参数,我们直接使用方法名即可,不需要括号,也不需要参数; 结果的值直接通过return返回即可 要去查看新列表的结果,一定要用list()去转换
方式二:用匿名函数来实现
print(list(filter(lambda m : m % 2 == 0, lst)))
map+匿名函数 map() 映射函数:会根据提供的函数对指定序列做映射。 语法:map(function,iterable,......) 会根据提供的括号内函数对给出的序列做一一映射 function为所指定的函数,iterable为所提供的序列,可为多个序列。
# 案例:计算列表[1,2,3,4,5]中每个元素的平方,返回新列表
lst = [1,2,3,4,5] # [1,4,9,16,25]
new_lst = []
# 方式一:用普通函数实现
def fun1(m):
# print(m * m)
new_lst.append(m * m)
for i in lst:
fun1(i)
print(new_lst)
def fun1(m):
# print(m * m)
return m * m
print(list(map(fun1,lst)))
# 方式二:用匿名函数来实现
print(list(map(lambda m: m * m,lst)))
3.函数的传递与日志函数的使用
在python中函数名可以作为参数来传递
def fun1():
print('fun1在执行')
def fun2(name): #name = fun1
print('fun2在执行')
name() #函数调用的语法 #name() = fun1()
fun2(fun1)
日志函数:函数中添加日志信息
# 案例1:在执行任何函数的时候,除了正常执行函数外,还有要输出下日志信息,如输入xx函数正在执行
# 解决方法:在每个函数中加上日志信息的输出
import logging
def fun1():
logging.warning('fun1函数正在执行')
print('fun1在执行')
def fun2(name): #name = fun1
logging.warning('fun2函数正在执行')
print('fun2在执行')
name() #函数调用的语法 #name() = fun1()
fun2(fun1)
# 问题:如果其他函数也有类似的需求,怎么做?
# 解决方法:将处理日志提取出来放在一个单独的函数中,
# 日志处理完之后再执行真正的业务代码
日志函数:专门写一个函数来处理日志信息
def log_info(fun_name): # 函数名
logging.warning('{}函数正在执行'.format(fun_name.__name__))
fun_name()
def fun1():
print('fun1在执行')
def fun2():
print('fun2在执行')
def info():
print('info在执行')
log_info(info)
log_info(fun2)
原本我要执行的info(),fun2() -->调用info(),fun2() 现在我们变成了调用log_info(info)、log_info(fun2) 问题:虽然需求实现了,但是我们调用的方法改变了? 解决方法:用装饰器来解决 -- 在不改变原来函数的代码的以及调用方式前提的前提下,去给此函数增加附属的功能
4. 装饰器的使用
定义语法: def log(func): def wrapper(*args, **kwargs): print('call %s():' % func.__name__) return func(*args, **kw) return wrapper 注意:log是装饰器的名字,自定义,要符合标识符的命名规范,以及见名知意 func:接受的一个函数名 return wrapper:装饰器的返回值是一个函数名,是装饰器里面定义的函数名 wrapper:函数名,自定义,要符合标识符的命名规范,以及见名知意,一般就是用wrapper print('call %s():' % func.__name__):装饰器添加的附属功能 return func(*args, **kw):这是装饰器传入参数函数名的调用,真正执行的函数本体 使用语法: @log def test(): pass
# 使用装饰器来解决执行函数添加日志,并且不改变调用方式的问题
import logging
# 装饰器的定义
def log(func):
def wrapper():
# 增加的附属功能
logging.warning('{}函数正在执行'.format(func.__name__))
# 返回执行函数本体
return func()
# 返回wrapper
return wrapper
# 装饰器的使用
@log
def fun1():
print('fun1在执行')
@log
def fun2():
print('fun2在执行')
@log
def info(name,addr):
print('姓名:{},地址:{}'.format(name,addr))
# 调用
fun2() # 真正执行的是装饰器里面的wrapper()
info('zs','北京') #真正执行的是装饰器里面的wrapper()
# 问题:如果有些函数带参,有些函数不带参,并且带参的个数不一致的情况,装饰器好像没办法匹配
5. 装饰器的定义
执行的函数带参不一致的处理
import logging
# 装饰器的定义
def log(func):
def wrapper(*args,**kwargs): #*args只能接受位置参数
# 增加的附属功能
logging.warning('{}函数正在执行'.format(func.__name__))
# 返回执行函数本体
return func(*args,**kwargs)
# 返回wrapper
return wrapper
# 装饰器的使用
@log
def fun1():
print('fun1在执行')
@log
def fun2(name):
print('fun2在执行',name)
@log
def info(name,addr):
print('姓名:{},地址:{}'.format(name,addr))
# 调用
fun1()
fun2('hhhhh') # 真正执行的是装饰器里面的wrapper()
info(name='zs',addr='北京') #真正执行的是装饰器里面的wrapper()