一.Python下的匿名函数
1.匿名函数的语法规则:
匿名函数(一般作为参数写到别人定义的函数中去,目的:变为动态的代码):用lambda关键字能创建小型的匿名函数,这种函数省略了def的声明。
其语法为:lambda [args1[,args2,args3...]]:expression(表达式)————即可以接多个参数,而后面只允许接表达式。冒号前面是形参,冒号后面是返回值。
def test(a,b):
return a+b
print(test(22,33)) #输出55f=lambda x,y:x+y
print(f(22,33)) #输出55
2.匿名函数的应用:
<1>应用一:
匿名函数的应用1
def test(a,b,func):
result=func(a,b)
return result
print(test(22,33,lambda x,y:x*y)) #输出726
<2>应用二:
匿名函数的应用2
#下面的代码有错误(列表的字典之间不能比大小)
# stus=[{'name':'zs','age':22},{'name':'老王','age':33},{'name':'aini','age':18}]
# stus.sort() #输出报错stus=[{'name':'zs','age':22},{'name':'老王','age':33},{'name':'aini','age':18}]
stus.sort(key=lambda x:x['age'])
print(stus) #输出[{'name': 'aini', 'age': 18}, {'name': 'zs', 'age': 22}, {'name': '老王', 'age': 33}]
<3>应用三:
匿名函数的应用3(关于python动态语言的应用)
#在python3中不能跑下面的程序(这是因为python3的input将输入的东西当作字符串,而python2中input将输入的东西当作表达式,raw_input将输入的东西当作表达式。)
def test(a,b,func):
result=func(a,b)
return result
while True:func_new=input('请输入你的操作:')
print(test(22,33,func_new))#在python3中也能跑
def test(a,b,func):
result=func(a,b)
return result
while True:
func_new=input('请输入你的操作:')
func_new=eval(func_new) #把字符串转换成可以执行的表达式。
print(test(22,33,func_new))
3.匿名函数的参数:
<1>匿名函数的默认参数
f=lambda x,y=2:x**y
print(f(2)) #输出4
print(f(2,4)) #输出16
<2>匿名函数的可变参数
f=lambda *args:sum(args)
print(f(1,2,3,4,5,6)) #输出21
<3>匿名函数的关键字参数
f=lambda **kwargs:kwargs.keys()
print(f(name='fentiao',age=10)) #输出dict_keys(['name', 'age'])f=lambda **kwargs:kwargs.values()
print(f(name='fentiao',age=10)) #输出dict_values(['fentiao', 10])
4.匿名函数的练习:
<1>练习一:
计算1+2+3+4+5的和
from functools import reduce
print(reduce(lambda x,y:x+y,[1,2,3,4,5]))
<2>练习二:
计算1的平方,2的平方,3的平方,4的平方,5的平方,并将其放入一个列表中
print(list(map(lambda x:x**2,range(1,6))))
<3>练习三:
计算10的阶乘
from functools import reduce
print(reduce(lambda x,y:x*y,range(1,11)))
<4>练习四:
(2018-携程-春招题)题目需求:
给定一个整形数组, 将数组中所有的0移动到末尾, 非0项保持不变;
在原始数组上进行移动操作, 勿创建新的数组;
# 输入:
第一行是数组长度, 后续每一行是数组的一条记录;
4
0
7
0
2
# 输出:
调整后数组的内容;
4
7
2
0
0
#方法一:
nums=[0,7,0,1,2,1,5,1,7,8,0,67,1,3,4] #输出[7, 1, 2, 1, 5, 1, 7, 8, 67, 1, 3, 4, 0, 0, 0]
print(sorted(nums,key=lambda x:1 if x==0 else 0)) #输出[7, 1, 2, 1, 5, 1, 7, 8, 67, 1, 3, 4, 0, 0, 0]
#方法二:
nums=[0,7,0,1,2,1,5,1,7,8,0,67,1,3,4] #输出[7, 1, 2, 1, 5, 1, 7, 8, 67, 1, 3, 4, 0, 0, 0]
print(sorted(nums,key=lambda x: x==0)) #输出[7, 1, 2, 1, 5, 1, 7, 8, 67, 1, 3, 4, 0, 0, 0]
二.Python下的装饰器
1.装饰器的含义:
装饰器:其实就是一个闭包,对外函数传入参数(该参数是一个函数),然后定义的内部函数对传进来的参数(函数)进行封装。然后再把封装好的内部函数作为返回值返回。
2.装饰器的语法规则:
<1>装饰器基础之无参:
def decorator(func): #固定格式
def wrapper():
print('~~~~')
func()
return wrapper
@decorator #语法糖,表示在执行fun1函数之前,先执行装饰器
def func1():
print('hello python')func1()
#输出 ~~~~
# hello python
当然也可以不写成语法糖。
def decorator(func):
def wrapper():
print('~~~~')
func()
return wrapperdef func1():
print('hello python')f=decorator(func1)
f()
#输出 ~~~~
# hello python
<2>装饰器基础之无参:
import time #导入时间模块
def decorator(func):
def wrapper():
print(time.time())
func()
return wrapper@decorator
def func1():
print('This is a function')func1()
#输出 1547965843.6613572
# This is a function
<3>装饰器基础之一个参数:
import time
def decorator(func):
def wrapper(args):
print(time.time())
func(args)
return wrapper@decorator
def func1(func_name):
print('This is function ' + func_name)func1('test')
#输出 1547965902.3124943
# This is function test
<4>装饰器基础之多个参数(可变参数):
import time
def decorator(func):
def wrapper(*args):
print(time.time())
func(*args)
return wrapper@decorator
def func1(func_name1,func_name2):
print('This is function ' + func_name1)
print('This is function ' + func_name2)func1('test1','test2')
#输出 1547965947.4943426
# This is function test1
# This is function test2
<5>装饰器基础之关键字参数:
import time
def decorator(func):
def wrapper(*args,**kwargs):
print(time.time())
func(*args,**kwargs)
return wrapper@decorator
def func1(func_name1,func_name2,**kwargs):
print('This is function ' + func_name1)
print('This is function ' + func_name2)
print(kwargs)func1('test1','test2',a=1,b=2,c=3)
#输出 1547965741.7117374
# This is function test1
# This is function test2
# {'a': 1, 'b': 2, 'c': 3}
<6>装饰器基础之函数带有返回值:
import time
def decorator(func):
def wrapper(*args,**kwargs):
start_time=time.time()
res=func(*args,**kwargs)
end_time=time.time()
print('运行时间为:%.6f' %(end_time-start_time))
return res
return wrapper@decorator
def fun_list(n):
return [i*2 for i in range(n)]@decorator
def fun_map(n):
return list(map(lambda x:x*2,range(n)))print(fun_list(50)) #值的注意的是:如果前面的装饰器中不加return res 那么打印出来的列表是none
print(fun_map(50)) #值的注意的是:如果前面的装饰器中不加return res 那么打印出来的列表是none#输出 运行时间为:0.000009
# [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98]
# 运行时间为:0.000011
# [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98]
3.装饰器的练习:
<1>练习一:装饰器实现一个函数计时器
import time
import random
import functools
import string#问题一:如何保留被装饰函数的函数名和帮助文档
li=[random.choice(string .ascii_letters) for i in range(100)]def decorator(func):
"""这是一个wrapper函数"""
@functools.wraps(func)
def wrapper():
start_time=time.time()
func()
end_time=time.time()
print('运行时间为:%.6f' %(end_time-start_time))
return wrapper@decorator
def con_add():
'''这是for循环实现拼接'''
s=''
for i in li:
s+=(i+',')
print(s)
@decorator
def join_add():
print(','.join(li))con_add()
join_add()
#输出 M,D,x,z,w,f,Z,y,b,b,p,K,C,c,a,g,h,i,W,F,J,T,V,X,t,a,F,l,G,I,X,I,A,c,X,W,P,c,o,l,j,h,m,R,g,w,L,w,R,j,L,i,u,t,t,v,u,F,K,z,d,m,p,R,l,Z,X,F,x,t,J,Y,I,u,e,N,v,A,h,u,M,e,c,T,r,P,V,l,A,n,S,B,H,h,T,f,d,F,N,W,
# 运行时间为:0.000074
# M,D,x,z,w,f,Z,y,b,b,p,K,C,c,a,g,h,i,W,F,J,T,V,X,t,a,F,l,G,I,X,I,A,c,X,W,P,c,o,l,j,h,m,R,g,w,L,w,R,j,L,i,u,t,t,v,u,F,K,z,d,m,p,R,l,Z,X,F,x,t,J,Y,I,u,e,N,v,A,h,u,M,e,c,T,r,P,V,l,A,n,S,B,H,h,T,f,d,F,N,W
# 运行时间为:0.000012
print(con_add.__doc__)
print(join_add.__doc__) #值的注意的是:如果前面的装饰器中不加 @functools.wraps(func),那么打印出来的是wrapper函数的注释(这是一个wrapper函数)
print(con_add.__name__) #值的注意的是:如果前面的装饰器中不加 @functools.wraps(func),那么打印出来的名字是wrapper
print(join_add.__name__)
#输出 运行时间为:0.000008
# 这是for循环实现拼接
# None
# con_add
# join_add
<2>练习二
创建装饰器, 要求如下:
# 1. 创建add_log装饰器, 被装饰的函数打印日志信息;
# 2. 日志格式为: [字符串时间] 函数名: xxx,运行时间:xxx,运行返回值结果:xxx
import time
import functools
def add_log(func):
@functools .wraps(func)
def wrapper(*args):
start_time=time.time()
res=func(*args)
end_time=time.time()
print('[%s] 函数名:%s,运行时间:%.6f,运行返回值结果:%s' \
%(time.ctime(),func.__name__,(end_time-start_time),res))
# return res
return wrapper
@add_log
def add(x,y):
time.sleep(1)
return x+y
# print(add(1,10))
add(1,10)
<3>练习三
编写装饰器实现,如果是root用户就能执行add函数,如果不是root用户就输出“不是root用户,不能添加用户”
import inspect
def decorator(func):
def wrapper(args):
#inspect.getcallargs返回值是字典,key值为:形参,value值为形参对应的实参
inspect_res=inspect.getcallargs(func,args)
print('inspect_res的返回值为:%s' %inspect_res)
if inspect_res.get('name')=='root':
func(args)
else:
print('你不是root用户,不能添加用户')
return wrapper
@decorator
def add_student(name):
print('添加学生信息...')
add_student('root')
#输出结果: inspect_res的返回值为:{'name': 'root'}
# 添加学生信息...
add_student('xin')
#输出结果: inspect_res的返回值为:{'name': 'xin'}
# 你不是root用户,不能添加用户
这里值的注意的是inspect模块的使用。
<4>练习四
编写装饰器required_ints, 条件如下:
1). 确保函数接收到的每一个参数都是整数; # 如何判断变量的类型?
type(s), isinstance(s,str)
2). 如果参数不是整形数, 抛出异常raise TypeError(“参数必须为整形”)
def required_ints(func):
def wrapper(*args,**kwargs):
for i in args+tuple(kwargs.values()):
if not isinstance(i,int):
raise TypeError('参数必须为整型')
return func(*args,**kwargs)
return wrapper
@required_ints
def add(*args,**kwargs):
# return sum(args)+sum(kwargs.values())
return sum((args+tuple(kwargs.values())))
print(add(1,2,3,65,67,1,a=1,b=2))
print(add(1,2,3,65,67,1.0,a=1,b=2))
<5>练习五:装饰器传入参数
def required_types(*kinds):
def required_ints(func):
def wrapper(*args):
for i in args:
if not isinstance(i,kinds):
# raise TypeError('参数必须为整型')
print('TypeError:参数必须为:',kinds)
break
else:
return func(*args)
return wrapper
return required_ints@required_types(int)
def add(*args):
return sum(args)
print(add(1,2,4,5,6))
# 输出 18
print(add(1,2,4.0,5,6))
# 输出 TypeError:参数必须为: (<class 'int'>,)
# None
<6>练习六:装饰器的执行顺序
def decorator_a(func):
print('Get in decorator_a')
def inner_a(*args,**kwargs):
print('Get in inner_a')
res = func(*args,**kwargs)
return res
return inner_adef decorator_b(func):
print('Get in decorator_b')
def inner_b(*args,**kwargs):
print('Get in inner_b')
res = func(*args,**kwargs)
return res
return inner_b
@decorator_b
@decorator_a
def f(x):
print('Get in f')
return x * 2print(f(1))
#输出 Get in decorator_a
# Get in decorator_b
# Get in inner_b
# Get in inner_a
# Get in f
# 2
import inspect
def decorator_login(func):
def wrapper(args):
if args in login_list:
print('登陆成功')
res=func(args)
else:
print('登陆失败')
return wrapper
def decorator(func):
def wrapper(args):
inspect_res=inspect.getcallargs(func,args)
print('inspect_res的返回值为:%s' %inspect_res)
if args=='root':
func(args)
else:
print('你不是root用户,不能添加用户')
return wrapper
login_list=['root','admin','redhat']
@decorator_login
@decorator
def add_student(name):
print('添加学生信息...')add_student('admin')
#输出 登陆成功
# inspect_res的返回值为:{'name': 'admin'}
# 你不是root用户,不能添加用户
add_student('root')
#输出 登陆成功
# inspect_res的返回值为:{'name': 'root'}
# 添加学生信息...
add_student('xin')
#输出 登陆失败