什么是高阶函数

  1. 变量可以指向函数
  2. 函数名也是变量

变量可以指向函数

例:求-10的绝对值

  1. print(abs(-10))
  2. print(abs)
  3. #bs()代表对函数的调用,abs是函数本身
  4. f=abs#变量f也是指向abs所指向的函数
  5. print(f(-10))
  6. #变量f也指向了abs函数的本身

image.png

函数名也是变量

函数名其实就是指向函数的变量

对于abs()这个函数,我们可以把函数名abs看成是一个变量,它指向计算绝对值的函数

  1. abs=10
  2. #print(abs(-10))
  3. # print(abs(-10))
  4. #TypeError: 'int' object is not callable
  5. print(abs)#10

既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称为高阶函数

  1. def add(x,y,f):
  2. return f(x)+f(y)
  3. print(add(-10,5,abs))#10+5=15

什么是函数式编程

把函数作为参数传入,这样的函数就称为高级函数,函数式编程就是指这种高度抽象的编程范式
python中内建的高阶函数有map、reduce、filter、sorted

map

map()函数接收两个参数,一个是函数,一个是序列,map将传入的函数依次作用到序列的每个元素,并把结果作为新的list返回

  1. #一般方法
  2. a = [1,2,3,4,5,6,7,8,9]
  3. def f(x):
  4. return x*x
  5. b=[]
  6. for i in a:
  7. b.append(f(i))
  8. print(b)
  9. #map实现
  10. map(f,a)
  11. print(type(map(f,a)))
  12. c=map(f,a)
  13. print(list(c))
  14. #[1, 4, 9, 16, 25, 36, 49, 64, 81]
  15. #a转化为字符列表
  16. s=str(a)
  17. d = map(str,a)
  18. print(list(d))
  19. #['1', '2', '3', '4', '5', '6', '7', '8', '9']
  1. a = [1,2,3,4]
  2. b=[10,20,30]
  3. def f(x,y):
  4. return x+y
  5. c=map(f,a,b)
  6. print(list(c))
  7. #[11, 22, 33]

reduce

reduce把一个函数作用在一个序列[x1,x2,x3…]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做积累计算。
reduce[(f,x1,x2,x3,x3)]=f(f(f(x1,x2),x3),x4)

  1. from functools import reduce
  2. #计算一个序列的求和
  3. a=[1,2,3,4,5,6,7,8,9,10]
  4. sum=0
  5. for i in a:
  6. sum+=i
  7. print(sum)
  8. def sumTest(x,y):
  9. return x+y
  10. b=reduce(sumTest,a)
  11. print(b)
  12. #55
  13. #55
  14. #计算列表成一个数
  15. a=[1,4,6,7]
  16. def fun(x,y):
  17. return x*10+y
  18. b=reduce(fun,a)
  19. print(b)
  20. #1467

filter

python中内建的filter()函数。和map()类似,filter()也接收一个函数和一个序列。和map()不同的是 ,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是Flase保留还是丢弃该元素

  1. #在一个函数列表中删掉偶数,保留奇数odd
  2. def is_odd(n):
  3. # if n%2==0:
  4. # return False
  5. # else:
  6. # return True
  7. return n%2==1
  8. b=filter(is_odd,[1,2,3,4,5,6,7,8,9,10])
  9. print(list(b))
  10. #[1, 3, 5, 7, 9]
  1. #在一个序列中删除空字符串
  2. a=['A','','B',None,'C',' ']
  3. def n_e(s):
  4. return s and s.strip()#去除两边空白
  5. b=filter(n_e,a)
  6. print(list(b))
  7. #['A', 'B', 'C']

sorted

当两个列表是字符串或者字典的时候,直接比较是没有意义的。通常规定,对于两个元素x和y,如果认为x《y,则返回-1,如果认为x==y,则返回0,如果认定想x>y则返回1。

  1. #对数值进行排序
  2. sort_list=sorted([2,33,45,32,-100,3,-9])
  3. print(sort_list)#默认升序排序
  4. #逆序用参数recerse
  5. sort_list=sorted([2,33,45,32,-100,3,-9],reverse=True)
  6. print(sort_list)
  7. sort_list=sorted(['a','ABC','D','ab','abc','d','C'])
  8. print(sort_list)#按ASCII码排序
  9. sort_list=sorted(['a','ABC','D','ab','abc','d','C'],reverse=True)
  10. print(sort_list)#逆序
  11. #接收key来自定义排序
  12. sort_list=sorted([2,33,45,32,-100,3,-9],key=abs)
  13. print(sort_list)#指定绝对值排序
  14. sort_list=sorted(['a','ABC','D','ab','abc','d','C'],reverse=True,key=str.lower)
  15. print(sort_list)#忽略大小写

image.png

匿名函数lambda

匿名函数,不需要显示自定义函数。计算f(x)=x2时,除了定义一个f(x)的函数外,还可以直接传入匿名函数

lambda表达式就是一个简单的函数,使用lambda声明的函数可以返回一个值,在调用函数时,直接使用lambda表达式的返回值。
lambda arg1,arg2,arg3...: <表达式>

其中arg1/arg2/arg3为函数的参数。<表达式>相当于函数体。运算结果是:表达式的运算结果
匿名函数有个限制,就是只能一个表达式,不用使用return,返回值就是该表达式的结果

匿名函数没有名字,不用担心函数名冲突,此外匿名函数也是一个函数对象,也可以把匿名函数赋值给一个变量,再利用变量来调用该函数

  1. f =lambda a,b,c:a+b+c
  2. print(f(1,2,3))
  3. #6
  4. m = map(lambda x:x*x,[1,2,3,4,5,6,7,8,9])
  5. print(list(m))
  6. #[1, 4, 9, 16, 25, 36, 49, 64, 81]
  1. class Student:
  2. def __init__(self,name,age):
  3. self.name=name
  4. self.age=age
  5. s1 =Student('zs',21)
  6. s2 =Student('ls',25)
  7. s3 =Student('ww',22)
  8. print("********年龄*****************")
  9. a= sorted([s1,s2,s3],key=lambda x:x.age)
  10. for i in a:
  11. print('name',i.name,'age',i.age)
  12. print("********名字ASCII码排序*****************")
  13. a = sorted([s1, s2, s3], key=lambda x: x.name)
  14. for i in a:
  15. print('name',i.name,'age',i.age)
  16. print("********名字ASCII码逆序排序*****************")
  17. a = sorted([s1, s2, s3], key=lambda x: x.name,reverse=True)
  18. for i in a:
  19. print('name',i.name,'age',i.age)

image.png

闭包

  1. 什么是闭包

闭包就是一个函数

  1. 如何创建闭包
    1. 要有内部函数的嵌套(外部函数、内部函数)
    2. 内部函数中要有外部函数的变量
    3. 外部函数必须有返回值,返回的是内部函数的函数名
  2. 如何使用闭包
  1. def sum(a,b):
  2. return a+b
  3. print(sum(1,2))
  4. def funout(n1):
  5. def funin(n2):
  6. return n1+n2
  7. return funin
  8. f= funout(1)
  9. c =f(2)
  10. print(c)
  11. #3
  1. def funout(n1):
  2. def funin(n2):
  3. #内部函数修改外部参数的变量
  4. nonlocal n1
  5. n1+=100
  6. return n1+n2
  7. return funin
  8. f= funout(1)
  9. c =f(2)
  10. print(c)
  11. #103
  1. #求两点间的距离
  2. import math
  3. def getDis(x1,y1,x2,y2):
  4. return math.sqrt((x1-x2)**2+(y1-y2)**2)
  5. a=getDis(1,1,0,0)
  6. print(a)
  7. def gdO(x1,y1):
  8. def gdI(x2,y2):
  9. return math.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2)
  10. return gdI
  11. a=gdO(1,1)
  12. b=a(0,0)
  13. print(b)
  14. #1.4142135623730951
  15. #1.4142135623730951

添加日志功能

  1. import time
  2. def witeLog(func):
  3. try:
  4. file=open("w.text",'a',encoding='utf-8')
  5. file.write('访问')
  6. file.write(func.__name__)
  7. file.write('\t')
  8. file.write("时间")
  9. file.write(time.asctime())
  10. file.write("\n")
  11. except Exception as e:
  12. print(e.args)
  13. finally:
  14. file.close()
  15. def fun1():
  16. witeLog(fun1)
  17. print("f1")
  18. def fun2():
  19. witeLog(fun2)
  20. print("f2")
  21. fun1()
  22. fun2()
  1. import time
  2. def witeLog(func):
  3. try:
  4. file=open("w.text",'a',encoding='utf-8')
  5. file.write('访问')
  6. file.write(func.__name__)
  7. file.write('\t')
  8. file.write("时间")
  9. file.write(time.asctime())
  10. file.write("\n")
  11. except Exception as e:
  12. print(e.args)
  13. finally:
  14. file.close()
  15. def fun1():
  16. #witeLog(fun1)
  17. print("f1")
  18. def fun2():
  19. #witeLog(fun2)
  20. print("f2")
  21. def funcOut(func):
  22. def funIn():
  23. witeLog(func)
  24. func()
  25. return funIn
  26. ff= funcOut(fun1)
  27. ff()
  28. fun2 = funcOut(fun2)
  29. 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))

image.png

偏函数

偏函数是用于对函数固定属性的函数,就是把一个函数某个参数固定住(也就是设置默认值),返回一个新函数,调用这个新函数更简单。

#将字符串按十进制转化为整数

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'))

image.png

#定义偏函数实现效果
from functools import  partial

new_int=partial(int,base=2)
print(new_int('111'))
print(new_int('1000111'))

image.png