python 函数(下)

1. 高阶函数

1.1 高阶函数的定义

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

1.2 高阶函数的特点

  1. 接受一个或多个函数作为参数
  2. 将函数作为返回值返回

PS :两个条件只要满足其一即可。

1.3 高阶函数的作用

  1. 增加灵活性
  2. 传入任意函数

2. 匿名函数

2.1 匿名函数的定义

匿名函数 lambda函数 就是专门用来创建一些简单的函数
lambda 函数是一种小的匿名函数。

2.2 匿名函数的语法:

lambda 参数:表达式
lambda arguments : expression

PS:
lambda 函数可接受任意数量的参数,但只能有一个表达式。

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

or

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

[运行结果如下:]

>>> 30
list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
re = lambda i: i % 2 == 0
print(list(filter(re, list1)))

[运行结果如下:]

[2, 4, 6, 8, 10]

3. 闭包

3.1 闭包的定义

• 将函数作为返回值也是高阶函数我们也称为闭包

3.2 闭包的好处

• 通过闭包可以创建一些只有当前函数能访问的变量
• 可以将一些私有数据藏到闭包中

3.3 形成闭包的条件

• 函数嵌套
• 将内部函数作为返回值返回
• 内部函数必须要使用到外部函数的变量(一般不能是全局变量),而返回的 那个函数内部不一定要return

3.4 语法

def 外部函数():
    ...
    def 内部函数():
        ...
    return 内部函数
# eg.1
def fun1(a, b):
    def fun2(x):
        return a * x + b    # 内部函数使用到外部函数
 
    return fun2     # 返回内部函数

嵌套函数fun2中的代码访问了a和b变量,fun2本身函数体内并不存在这两个变量,所以会逐级向外查找,往上走一层就找到了来自主函数fun1传递的a, b。若往外直至全局作用域都查找不到的话代码会抛异常。不管主函数fun1下面嵌套了多少个函数,这些函数都在其作用域内,都可以在fun1作用域内被调用。

# eg.2
def fun3():
    a = 1
    b = 2
 
    def fun2(x):
        print(a * x + b)     # 内部函数使用到外部函数
 
 
    return fun2             # 返回内部函数
# eg.3
def fun(a, b):
   def fun4(c):
       def fun5(x):
           return a * (x ** 2) + b * x + c      # 内部函数使用到外部函数

       return fun5          # 返回内部函数

   return fun4          # 返回内部函数

4. 装饰器

4.1 装饰器的引入

我们可以直接通过修改函数中的代码来完成需求,但是会产生以下一些问题:
• 如果修改的函数多,修改起来会比较麻烦
• 不方便后期的维护
• 这样做会违反开闭原则(ocp)
• 程序的设计,要求开发对程序的扩展,要关闭对程序的修改

4.2 装饰器的作用

装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。
它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。装饰器是解决这类问题的绝佳设计,
有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。

• 通过装饰器,可以在不修改原来函数的情况下来对函数进行扩展

• 在开发中,我们都是通过装饰器来扩展函数的功能的

• 装饰器的理念是对原函数、对象的加强,相当于重新封装,所以一般装饰器函数都被命名为wrapper(),意义在于包装。函数只有在被调用时才会发挥其作用。比如@logging装饰器可以在函数执行时额外输出日志,@cache装饰过的函数可以缓存计算结果等等

• 概括的讲,装饰器的作用就是为已经存在的函数或对象添加额外的功能。

• 简言之,python装饰器就是用于拓展原来函数功能的一种函数,这个函数的特殊之处在于它的返回值也是一个函数,使用python装饰器的好处就是在不用更改原函数的代码前提下给函数增加新的功能。

4.3 装饰器的使用

import time
def fun():
    print("hello")
    time.sleep(1)
    print("world")

这是我们最原始的的一个函数,然后我们试图记录下这个函数执行的总时间,那最简单的做法就是:

直接篡改原函数

import time
def fun():
    Time1 = time.time()
    print("hello")
    time.sleep(1)
    print("world")
    Time2 = time.time()
    
    Time3 = (Time2 - Time1)*1000
    print("time is %d ms" %Time3)

但是,如果你的上司和你说:“这段是我们公司的核心代码,你不能更改,也别执行个千万次,我心疼我那几个机器”。那你是不是就是束手无策了?不,并不是。这时候装饰器就可以发挥作用了。

我们先实现一个最简陋的装饰器,不使用任何语法糖和高级语法,看看装饰器最原始的面貌:

import time


def Fun(fun):
    def fun1():
        Time1 = time.time()
        fun()
        Time2 = time.time()
        Time = (Time2 - Time1) * 1000
        print("time is %d ms" % Time)

    return fun1      # 返回包装过的函数


@Fun
def fun():
    print("hello")
    time.sleep(1)
    print("world")


if __name__ == '__main__':
    fun()

既不需要侵入,也不需要函数重复执行
这就是最原始的装饰器,它的参数是一个函数,然后返回值也是一个函数。其中作为参数的这个函数fun()就在返回函数fun1()的内部执行。然后在函数fun()前面加上@Fun,fun()函数就相当于被注入了计时功能,现在只要调用fun(),它就已经变身为“新的功能更多”的函数了。
所以这里装饰器就像一个注入符号:有了它,拓展了原来函数的功能既不需要侵入函数内更改代码,也不需要重复执行原函数。

4.4 带参数的装饰器

import time


def Fun(fun):
    def fun1(a, b):
        Time1 = time.time()
        fun(a, b)
        Time2 = time.time()
        Time = (Time2 - Time1) * 1000
        print("time is %d ms" % Time)

    return fun1


@Fun
def fun(a, b):
    time.sleep(1)
    print('result is {}'.format(a + b))


if __name__ == '__main__':
    fun(1, 2)

4.5 带不定参数的装饰器

import time


def Fun(fun):
    def fun1(*args, **kwargs):
        Time1 = time.time()
        fun(*args, **kwargs)
        Time2 = time.time()
        Time = (Time2 - Time1) * 1000
        print("time is %d ms" % Time)

    return fun1


@Fun
def fun(a, b):
    time.sleep(1)
    print('result is {}'.format(a + b))


if __name__ == '__main__':
    fun(1, 2)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值