python函数三

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/shell_x/article/details/102665647

高阶函数

满足2个条件任意一个都是高阶函数

  • 接受函数作为参数
  • 将函数作为返回值的函数也是高阶函数

当我们使用一个函数作为参数时,实际上就是将指定的代码传给目标函数

 l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
new_l = []
def fn1(i): # 定义一个函数用来检测序列中的数是否是偶数
    if i % 2 == 0:
        return True
    return False
def fn2(i): # 检测序列是否大于5
    if i > 5:
        return True
    return False
def fn3(i): # 检测3的倍数
    if i % 3 == 0:
        return True
    return False

def fn(func, lis):
    for n in lis:
        if func(n):
            new_l.append(n)
    return new_l
r1 = fn(fn1, l)
print(r1) 
# [2, 4, 6, 8, 10]
# r2 = fn(fn2, l)
# print(r2) 
# [6, 7, 8, 9, 10]  
# r3 = fn(fn3, l)
# print(r3)
# [3, 6, 9]   

匿名函数

lambda表达式,用来创建一些简单的函数,它是函数创建的另一种方式,其实现了python中的最小函数
语法:lambda 参数列表 :返回值

  • 匿名函数最大的好处是只会调用一次,用完之后会从内存中消失
  • 匿名函数一般都是作为参数使用,其他地方不用
    你会发现直接使用lambda返回的是内存地址,且该内存地址没有函数名,但fn函数有(函数名就是fn),所以lambda称为匿名函数
def fn(x):
    return x*x
r = fn(3)
print(r)
print(fn)
# 相当于
print(lambda x:x*x)
print((lambda x:x*x)(3))
# <function fn at 0x000001F100215048>
# 9
# <function <lambda> at 0x00000208573755E8>
# 9
fn = lambda a, b:a+b
print(fn(1,1))
# 2

匿名函数一般作为参数使用,但上述方法是直接使用,我们引入
filter(funcation, sequence)

  1. 可以从序列中过滤出符合条件的元素,保存到另一个序列中
  2. 参数:
  • 函数(function),根据该函数来过滤序列(可迭代结构),可有可无
  • 序列(sequence),需要过滤的序列(可迭代结构)
  1. 返回值:
  • 过滤后的新序列
l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
new_l = []
def fn1(i): # 定义一个函数用来检测序列中的数是否是偶数
    if i % 2 == 0:
        return True
    return False
r = filter(fn1,l)
print(r) # 其返回的扔是filter对象
print(list(r)) # 加list即可返回新序列
# <filter object at 0x00000140872FD6C8>
# [2, 4, 6, 8, 10]

l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
r = filter(None,l)
print(r)
print(list(r))
# [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
r = filter(lambda x:x*x,range(10))
print(r)
print(list(r))
# <filter object at 0x0000023C57D474C8>
# [1, 2, 3, 4, 5, 6, 7, 8, 9]

map()

  • map()函数可以对可迭代对象中所有元素做指定的操作,然后将其添加到一个新的对象中返回
l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
r = map(lambda i:i+1,l)
print(r)
print(tuple(r)) # 也可用元组返回新的序列
# (2, 3, 4, 5, 6, 7, 8, 9, 10, 11)

sort()

  • sort()函数可以对列表当中的元素进行排序
    sort之前有讲过,这里介绍另一种方法,在参数值加入函数
lis = [1, 5, 4, 2, 6, '8', '6']
r = lis.sort(key = int)
print(r)
print(lis)
# None
# [1, 2, 4, 5, 6, '6', '8']

sorted()

  • 会返回一个新的列表
lis = [1, 5, 4, 2, 6, '8', '6']
r = sorted(lis, key = int)
print(r)
# [1, 2, 4, 5, 6, '6', '8']

闭包

  1. 通过闭包可以创建一些只有当前函数才能访问的对象,还可以将一些私有的对象藏到闭包中
  • 当我们不希望别人修改我们的数据时,将数据放入函数内部,不要放到全局变量中
  1. 形成闭包的条件
  • 函数嵌套
  • 将内部函数作为返回值返回
  • 内部函数必须使用到外部函数的变量
r = []
def avg():
    r = []
    def count(n):
        r.append(n)
        return sum(r)/len(r)

    return count # 这里返回的是count函数对象
a = avg() # 我们用a接受avg函数,实际上接受的是avg的返回值,其返回的是count对象
print(a(10)) # a(10)实际上是count(10)
print(r) # 我们打印r可以看到,我们在内部函数修改了列表r,全局变量中的r没有改变
# 10.0
# []

装饰器的引入

当我想修改一个函数时,我们直接修改函数体即可,但当我们向修改多个函数,就会产生一些问题

  • 修改数量很多
  • 不方便后期的维护
  • 会违反开闭原则(ocp),程序设计,要求对程序的扩展,但要关闭对程序的修改
    不修改原函数对函数进行修改
def add(a, b):
    return a+b
def expand(a, b):
    print('函数执行前')
    r = add(a, b) 
    print('函数执行后')   
    return r
r = expand(1, 1)    
print(r)
# 函数执行前
# 函数执行后
# 2

如果我想要在更改其他函数,该expand就不好用了,也要修改,那我还不如一个一个函数改,下面我们使用装饰器

装饰器的使用

def add(a, b):
    return a+b


def decorator(old):
    def new_func(*args, **kwargs):
        print('我来自装饰器')
        r = old(*args, **kwargs)
        return r
    return new_func
r = decorator(add)
print(r(1, 1))

@decorator
def baybay():
    print('拜拜~')
baybay()
# 我来自装饰器
# 2
# 我来自装饰器
# 拜拜~

decorator(old)类似于这样的函数就是一个装饰器,通过装饰器可以不在修改原函数的情况下,对函数进行扩展
在开发中都是通过装饰器来扩展函数功能

猜你喜欢

转载自blog.csdn.net/shell_x/article/details/102665647
今日推荐