什么是高阶函数
- 变量可以指向函数
- 函数名也是变量
变量可以指向函数
例:求-10的绝对值
print(abs(-10))
print(abs)
#bs()代表对函数的调用,abs是函数本身
f=abs#变量f也是指向abs所指向的函数
print(f(-10))
#变量f也指向了abs函数的本身
函数名也是变量
函数名其实就是指向函数的变量
对于abs()这个函数,我们可以把函数名abs看成是一个变量,它指向计算绝对值的函数
abs=10
#print(abs(-10))
# print(abs(-10))
#TypeError: 'int' object is not callable
print(abs)#10
既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称为高阶函数
def add(x,y,f):
return f(x)+f(y)
print(add(-10,5,abs))#10+5=15
什么是函数式编程
把函数作为参数传入,这样的函数就称为高级函数,函数式编程就是指这种高度抽象的编程范式
python中内建的高阶函数有map、reduce、filter、sorted
map
map()函数接收两个参数,一个是函数,一个是序列,map将传入的函数依次作用到序列的每个元素,并把结果作为新的list返回
#一般方法
a = [1,2,3,4,5,6,7,8,9]
def f(x):
return x*x
b=[]
for i in a:
b.append(f(i))
print(b)
#map实现
map(f,a)
print(type(map(f,a)))
c=map(f,a)
print(list(c))
#[1, 4, 9, 16, 25, 36, 49, 64, 81]
#a转化为字符列表
s=str(a)
d = map(str,a)
print(list(d))
#['1', '2', '3', '4', '5', '6', '7', '8', '9']
a = [1,2,3,4]
b=[10,20,30]
def f(x,y):
return x+y
c=map(f,a,b)
print(list(c))
#[11, 22, 33]
reduce
reduce把一个函数作用在一个序列[x1,x2,x3…]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做积累计算。reduce[(f,x1,x2,x3,x3)]=f(f(f(x1,x2),x3),x4)
from functools import reduce
#计算一个序列的求和
a=[1,2,3,4,5,6,7,8,9,10]
sum=0
for i in a:
sum+=i
print(sum)
def sumTest(x,y):
return x+y
b=reduce(sumTest,a)
print(b)
#55
#55
#计算列表成一个数
a=[1,4,6,7]
def fun(x,y):
return x*10+y
b=reduce(fun,a)
print(b)
#1467
filter
python中内建的filter()函数。和map()类似,filter()也接收一个函数和一个序列。和map()不同的是 ,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是Flase保留还是丢弃该元素
#在一个函数列表中删掉偶数,保留奇数odd
def is_odd(n):
# if n%2==0:
# return False
# else:
# return True
return n%2==1
b=filter(is_odd,[1,2,3,4,5,6,7,8,9,10])
print(list(b))
#[1, 3, 5, 7, 9]
#在一个序列中删除空字符串
a=['A','','B',None,'C',' ']
def n_e(s):
return s and s.strip()#去除两边空白
b=filter(n_e,a)
print(list(b))
#['A', 'B', 'C']
sorted
当两个列表是字符串或者字典的时候,直接比较是没有意义的。通常规定,对于两个元素x和y,如果认为x《y,则返回-1,如果认为x==y,则返回0,如果认定想x>y则返回1。
#对数值进行排序
sort_list=sorted([2,33,45,32,-100,3,-9])
print(sort_list)#默认升序排序
#逆序用参数recerse
sort_list=sorted([2,33,45,32,-100,3,-9],reverse=True)
print(sort_list)
sort_list=sorted(['a','ABC','D','ab','abc','d','C'])
print(sort_list)#按ASCII码排序
sort_list=sorted(['a','ABC','D','ab','abc','d','C'],reverse=True)
print(sort_list)#逆序
#接收key来自定义排序
sort_list=sorted([2,33,45,32,-100,3,-9],key=abs)
print(sort_list)#指定绝对值排序
sort_list=sorted(['a','ABC','D','ab','abc','d','C'],reverse=True,key=str.lower)
print(sort_list)#忽略大小写
匿名函数lambda
匿名函数,不需要显示自定义函数。计算f(x)=x2时,除了定义一个f(x)的函数外,还可以直接传入匿名函数
lambda表达式就是一个简单的函数,使用lambda声明的函数可以返回一个值,在调用函数时,直接使用lambda表达式的返回值。lambda arg1,arg2,arg3...: <表达式>
其中arg1/arg2/arg3为函数的参数。<表达式>相当于函数体。运算结果是:表达式的运算结果
匿名函数有个限制,就是只能一个表达式,不用使用return,返回值就是该表达式的结果
匿名函数没有名字,不用担心函数名冲突,此外匿名函数也是一个函数对象,也可以把匿名函数赋值给一个变量,再利用变量来调用该函数
f =lambda a,b,c:a+b+c
print(f(1,2,3))
#6
m = map(lambda x:x*x,[1,2,3,4,5,6,7,8,9])
print(list(m))
#[1, 4, 9, 16, 25, 36, 49, 64, 81]
class Student:
def __init__(self,name,age):
self.name=name
self.age=age
s1 =Student('zs',21)
s2 =Student('ls',25)
s3 =Student('ww',22)
print("********年龄*****************")
a= sorted([s1,s2,s3],key=lambda x:x.age)
for i in a:
print('name',i.name,'age',i.age)
print("********名字ASCII码排序*****************")
a = sorted([s1, s2, s3], key=lambda x: x.name)
for i in a:
print('name',i.name,'age',i.age)
print("********名字ASCII码逆序排序*****************")
a = sorted([s1, s2, s3], key=lambda x: x.name,reverse=True)
for i in a:
print('name',i.name,'age',i.age)
闭包
- 什么是闭包
闭包就是一个函数
- 如何创建闭包
- 要有内部函数的嵌套(外部函数、内部函数)
- 内部函数中要有外部函数的变量
- 外部函数必须有返回值,返回的是内部函数的函数名
- 如何使用闭包
def sum(a,b):
return a+b
print(sum(1,2))
def funout(n1):
def funin(n2):
return n1+n2
return funin
f= funout(1)
c =f(2)
print(c)
#3
def funout(n1):
def funin(n2):
#内部函数修改外部参数的变量
nonlocal n1
n1+=100
return n1+n2
return funin
f= funout(1)
c =f(2)
print(c)
#103
#求两点间的距离
import math
def getDis(x1,y1,x2,y2):
return math.sqrt((x1-x2)**2+(y1-y2)**2)
a=getDis(1,1,0,0)
print(a)
def gdO(x1,y1):
def gdI(x2,y2):
return math.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2)
return gdI
a=gdO(1,1)
b=a(0,0)
print(b)
#1.4142135623730951
#1.4142135623730951
添加日志功能
import time
def witeLog(func):
try:
file=open("w.text",'a',encoding='utf-8')
file.write('访问')
file.write(func.__name__)
file.write('\t')
file.write("时间")
file.write(time.asctime())
file.write("\n")
except Exception as e:
print(e.args)
finally:
file.close()
def fun1():
witeLog(fun1)
print("f1")
def fun2():
witeLog(fun2)
print("f2")
fun1()
fun2()
import time
def witeLog(func):
try:
file=open("w.text",'a',encoding='utf-8')
file.write('访问')
file.write(func.__name__)
file.write('\t')
file.write("时间")
file.write(time.asctime())
file.write("\n")
except Exception as e:
print(e.args)
finally:
file.close()
def fun1():
#witeLog(fun1)
print("f1")
def fun2():
#witeLog(fun2)
print("f2")
def funcOut(func):
def funIn():
witeLog(func)
func()
return funIn
ff= funcOut(fun1)
ff()
fun2 = funcOut(fun2)
fun2()
装饰器
在python中就是一种闭包,它可以使闭包的方式更简单
import time
def witeLog(func):
try:
file=open("s.text",'a',encoding='utf-8')
file.write('访问')
file.write(func.__name__)
file.write('\t')
file.write("时间")
file.write(time.asctime())
file.write("\n")
except Exception as e:
print(e.args)
finally:
file.close()
def funcOut(func):
def funIn():
witeLog(func)
func()
return funIn
@funcOut
def fun1():
print("f1")
def fun2():
print("f2")
#@funcOut == fun1 = funcOut(fun1)
fun1()
fun2()
#给foo函数,新增功能:在foo函数,输出’I am foo‘
def funcOut(func):
def funIn():
print('I am foo')
func()
return funIn
@funcOut
def foo():
print("foo函数正在运行")
foo()
#给foo函数,新增功能:在foo函数,输出’I am foo‘
def funcOut(func):
print('装饰器1')
def funIn():
print('I am foo')
func()
return funIn
def funOut2(func):
print("装饰器2")
def funIn():
print("hello")
func()
return funIn
@funOut2
@funcOut
#离功能函数最近的装饰器先运行
def foo():
print("foo函数正在运行")
foo()
#带2个参数的装饰器
import time
def witelog(func):
print("访问了方法名",func.__name__,"\t时间",time.asctime())
def funOut(func):
def funIn(x,y):
witelog(func)
return func(x,y)
return funIn
@funOut
def sum(a,b):
return a+b
s = sum(10,20)
print(s)
import time
# #*args可变参数,元组可传入多个参数
# *kwargs可以传入字典参数
def funOut(func):
def funIn(*args,**kwargs):
witelog(func)
return func(*args,**kwargs)
return funIn
def witelog(func):
print("访问了方法名",func.__name__,"\t时间",time.asctime())
@funOut
def sum(a,b):
return a+b
@funOut
def add(a,b,c):
return a+b+c
print(sum(10,20))
print(add(10,20,30))
偏函数
偏函数是用于对函数固定属性的函数,就是把一个函数某个参数固定住(也就是设置默认值),返回一个新函数,调用这个新函数更简单。
#将字符串按十进制转化为整数
print(int('12345'))
#base他进制转化为十进制
print("八进制转十进制",int('3267',base=8))
print("十六进制转十进制",int("8A",16))
print("二进制转十进制",int("1001001",base=2))
print("二进制转十进制",int("1011101",base=2))
print("二进制转十进制",int("10111001",base=2))
#base可以放到一个函数里面定义
def new_int(s):
return int(s,base=2)
print(new_int('111'))
print(new_int('1000111'))
#定义偏函数实现效果
from functools import partial
new_int=partial(int,base=2)
print(new_int('111'))
print(new_int('1000111'))