Python

python 基础知识第12讲:匿名函数、闭包、装饰器

2019-07-24  本文已影响49人  小海怪的互联网

1. 匿名函数

lambda表达式
lambda函数表达式专门用来创建一些简单的函数,它是函数创建的另外一种方式
是一种语法糖,一般用来完成比较简单的功能,复杂功能还需要写常规的函数。
匿名函数一般都是作为参数使用,其他地方一般不用

  • 语法 lambda 参数列表[a,b,c...] : 返回值
    例:(lambda a,b : a+b)(10,20)
    我们来看下面一下代码案例:
def fn5(a,b):
    return a + b
print(fn5(23,56))

将其换成lambda表达式后,等价形式如下:

fn6 = lambda a,b:a+b
print(fn6(30,20))

还可以直接print写到一起看下面代码:

print((lambda a,b : a+b)(10,20))

2.filter过滤器

filter(function, iterable)
可以从序列当中过滤出符合条件的元素,保存到一个新的序列中
参数一 传递函数 参数二 需要过滤的序列
返回值 过滤后新的序列

我们利用lambda来完成过滤列表 的一些内容:

l = [1,2,3,4,5,6,7,8,9,10]
r = filter(lambda i : i > 5,l)
print(list(r))

3.map()

map()函数可以对可迭代对象中所有的元素做指定操作,然后将其添加到一个新的对象返回

l = [1,2,3,4,5,6,7,8,9,10]
r = map(lambda i : i + 1,l)
print(list(r))

4.sort()

该方法用来对列表当中的元素进行排序;
sort()方法是直接默认比较列表中元素的大小;
在sort()函数中可以接收一个关键字参数 key;
key需要一个函数作为参数;

# sort()方法是直接默认比较列表中元素的大小,是按照字符串进行比较,此时的数据类型要一致;
l = ['bb','aaaa','c','fff','dddddddd']
l.sort()
print(l)
# 我们改为按长度进行比较,在sort()函数中可以接收一个关键字参数 key;key需要一个函数作为参数
l = ['bb','aaaa','c','fff','dddddddd']
l.sort(key= len)
print(l)

执行结果:
['c', 'bb', 'fff', 'aaaa', 'dddddddd']

# 在sort()函数中可以接收一个关键字参数 key;
key需要一个函数作为参数
l = [2,3,'1',3,'5','4']
l.sort(key=int)
print(l)

执行结果:['1', 2, 3, 3, '4', '5']
以上代码也是对高级函数的应用

5.sorted()

返回值 是一个新的列表

l = [2,3,'1',3,'5','4']
 #返回值 返回一个新的列表
print('排序前:',l)
r = sorted(l,key=int)
print('排序后:',r)

6.闭包

将函数作为返回值返回,也是一种高阶函数(闭包)

好处:通过闭包可以创建一些只有当前函数可以访问到的变量(可以将一些私有的数据藏到闭包当中)

形成闭包的条件

1.函数嵌套
2.将内部函数作为返回值返回
3.内部函数必须要使用到外部函数的变量

闭包使用时机

当我们有些数据不希望被别人访问和修改的时候,这样做可以保证我们数据的安全性

def fn():
    a = 10
    # 在函数内部在定义一个函数
    def inner():
        print('我是fn2',a)
    # 将内部函数 inner()作为返回值返回
    return inner
# r是一个函数,是调用fn()后返回的函数
# 这个函数在fn()内部定义的,并不是全局函数
# 所以这个函数总是能访问到fn()函数内部的变量
r = fn()
r()

我们来看一下闭包的案例代码:

# 求多个数的平均值
def make_average():
    # 创建一个空的列表
    nums = []
    # 创建一个函数,用来求平均值
    def average(n):
        nums.append(n)
        # 求平均值
        return sum(nums)/len(nums)
    return average
avg = make_average()
print(avg(30))

7.装饰器的引用

我们先一段案例代码:

# 打印开始计算 打印计算结束
def add(a,b):
    # 求任意两个数的和
    # print('计算开始...')
    r = a + b
    # print('计算结束...')
    return r
def mul(a,b):
    # 求任意两个数的积
    return a * b
r = add(1,2)
print(r)

通过刚才以上的步骤来实现当前的这个需要我们发现了以下一些问题:
1.如果要修改的函数过多,修改起来比较麻烦
2.不方便后期维护
3.会违反一个开闭原则(ocp)

我们在开发的时候 要求可以开放对程序的扩展,但是要关闭对程序的修改
在不修改原函数的情况下,来对函数进行扩展

看一下下面的代码断:

def new_add(a,b):
    print('函数开始执行......')
    r = add(a,b)
    print('函数执行结束......')
    return r
s= new_add(1,2)
print(s)

通过上面的例子,我们想对原有函数进行扩展的话,我们要写N多个新的函数来支撑,不够灵活

8.装饰器的使用

我们先看一段代码:

def start_end(old):
    # 用来对其他函数进行扩展 是其他函数可以在执行前打印执行开始,执行后打印执行结束
    # 创建一个函数 # *args 接收的是所有的位置参数
    # **kwargs 接收所有的关键字参数
    def new_function(*args,**kwargs):
        print('开始执行.....')
        # 调用被扩展的函数
        result = old(*args,**kwargs)
        print('开始结束.....')
        return result
    # 返回函数
    return new_function
f = start_end(fn)
f2 = start_end(add)
# r = f()
r = f2(123,456)
print(r)

像 start_end(old)这种函数我们就称之为装饰器;
通过装饰器 可以在不修改原来函数的基础之上来对函数进行扩展,在实际开发当中,我们都是通过装饰器来扩展原有函数的功能

8.1装饰器的另一种写法

可以在新定义的函数前面增加 @函数名 对原有函数进行扩展

@fn
def fn1()
    print('扩展')

fn1()
上一篇下一篇

猜你喜欢

热点阅读