python基础——函数(三)

本文介绍了Python中的函数式编程特性,包括函数作为对象的使用,如赋值给变量、存储在数据结构中和作为参数及返回值。重点讲解了map、filter和reduce函数以及它们在处理可迭代对象时的应用。此外,还详细探讨了装饰器的概念,包括闭包和如何创建带参数的装饰器,强调了装饰器在不修改原函数代码的情况下扩展功能的能力。
摘要由CSDN通过智能技术生成

如有兴趣了解更多请关注我的个人博客https://07xiaohei.com/

(四)函数式编程

Python是面向对象的程序设计语言,也是面向过程的程序语言,同时也支持函数式编程。

Pyhon标准库functools 提供了若干关于函数的函数,提供了Haskell和Standard ML中的函数式程序设计工具。

Python中的函数与其他数据类型处于平等地位,因此函数可以赋值给变量,可以作为参数传入其他函数,存储在其他数据结构中,或者作为函数的返回值。

1. 作为对象的函数:

函数在Python中是作为对象存在的,故函数对象可以赋值给变量,然后调用该变量。

def printself():
    print("123321")
copyfun = printself
copyfun()

数据结构内的函数:函数作为对象,也可以存储数据结构内部。

def fun1():
    print("fun1")
def fun2():
    print("fun2")
def fun3():
    print("fun3")
map_fun = {1:fun1,2:fun2,3:fun3}
map_fun[2]()
#运行结果:
# fun2

函数作为参数和返回值:函数可以作为其他函数的参数和返回值,接受函数作为输入或返回函数的函数叫做高阶函数。

def fun_use(fun,list_use):
    return fun(list_use)
print(fun_use(max,[1,2,3,4,5,6,3.4,7.2]))
# 运行结果:
# 7.2

def add(a,b):
    return a+b
def sub(a,b):
    return a-b
def fun_high(x):
    if x==1:
        return add
    elif x==2:
        return sub
    else:
        return None
fun_use = fun_high(1)
print(fun_use(2,1))
fun_use = fun_high(2)
print(fun_use(2,1))
#运行结果:
# 3
# 1

函数名实际上也是变量,可以让函数名指向其他对象,但是这样会导致原有的函数无法使用。

def add(a,b):
    return a+b
add =10
print(add)
#运行结果:
# 10

嵌套函数、Lambda表达式也是函数式编程的一部分,详见之前的博客,下面介绍更进一步的内容。

2. Map、Filter 和 Reduce:
(1) map函数:

map 函数的功能是对可迭代对象中的每个元素都调用指定的函数,并返回一个map对象的iterator迭代器(可以转化为list对象)。

语法格式:map(function, iterable)

function参数表示传入的函数,可以是内置函数、自定义函数或者 lambda 匿名函数,iterable表示可迭代对象,可以是列表、元组等,允许一到多个。

一般用于对某个集合对象的全部值执行某个特定操作。

map() 函数由 C 语言实现,执行效率高。

例子如下:

list_use = [1,2,3,4,5,6,7,8,9]
list_new = list(map(lambda x:x*2, list_use))
print(list_new)
# 运行结果:
# [2, 4, 6, 8, 10, 12, 14, 16, 18]
(2) fiter函数:

filter函数的功能是对传入的可迭代对象中的每个元素,都进行函数判断,并返回True或者False,最后将返回 True 的元素组成一个新的可遍历的集合对象,返回其迭代器。

语法格式:filter(function, iterable)

function参数表示传入的函数,可以是内置函数、自定义函数或者 lambda 匿名函数,iterable表示可迭代对象,可以是列表、元组等,允许一到多个。

一般用于筛除可迭代对象的不想要的项。

list_use = [1,2,3,4,5,6,7,8,9]
list_new = list(filter(lambda x:x%2==0, list_use))
print(list_new)
# 运行结果:
# [2, 4, 6, 8]
(3)redeuce函数:

reduce() 函数通常用来对一个集合做一些累积操作。

语法格式:reduce(function, iterable)

function规定必须传入一个包含 2 个参数的函数;iterable 表示可迭代对象,可以是列表、元组等,允许一到多个。

reduce() 函数在Python 3.x 中已经从内置函数中被移除,在functools模块使用 ,需要导入functools模块。

reduce 函数一般用于总结或者概述数据集。

import functools
list_use = [3,4,5,6,7]
list_new = functools.reduce(lambda x,y:x+y, list_use)
print(list_new)
# 运行结果:
# 25
3. 函数装饰器:
(1)闭包:

是指在函数中嵌套其他函数时引用外部函数变量,即在一个内部函数中,对外部作用域的变量进行引用,内部函数即为闭包。

一般情况下,内部函数是外部函数的返回值。

闭包无法修改外部函数的局部变量。

举例:

def add_two(a):
    def add_new(b):
        return a+b
    return add_new
print(add_two(2)(3))
# 运行结果:
# 5
(2)装饰器:

是闭包的一个应用,能够使得代码更简短。

装饰器是用于拓展原函数功能的一种函数,不需要修改原函数的内容和调用。

装饰器常用于授权、日志等行为。

语法格式:

def 装饰器函数名(唯一形参):

函数体

@装饰器函数名

def 被装饰的函数名(形参列表):

函数体

使用时直接调用被装饰的函数名即可。

装饰器函数的形参需要一个函数作为参数传入,同时需要在内部代码块执行该函数,以保证被装饰函数的正确执行。

传参时和带参数时需要装饰器函数嵌套函数,后面进行介绍。

Python内置了3种函数装饰器,分别是@staticmethod、@classmethod 和@property,我们也可以自己定义函数装饰器。

装饰器完成的内容:

  • 将被装饰的函数作为参数传给装饰器函数(后面->前面)。
  • 将被装饰的函数的返回值替换成装饰器函数的返回值(前面->后面)。

实际上,就是把装饰器函数的功能按一定逻辑顺序加入到被装饰的函数当中,使得原函数不需要修改。

因此,不用@函数也可以完成装饰器的功能,只是相对而言阅读比较困难。

例子如下:

def use_decorator_fun(used_for_decorator_fun):
    print("添加新功能的位置,在被装饰的函数执行之前执行")
    used_for_decorator_fun()
    print("添加新功能的位置,在被装饰的函数执行之后执行")
    return True
@use_decorator_fun
def used_for_decorator_fun():
    print("执行正常功能中")
    for i in range(1,11,2):
        print(i,end=',')
    print("\n执行完毕")

result = used_for_decorator_fun
if result:
    print("执行成功")
# 运行结果:
# 添加新功能的位置,在被装饰的函数执行之前执行
# 执行正常功能中
# 1,3,5,7,9,
# 执行完毕
# 添加新功能的位置,在被装饰的函数执行之后执行
# 执行成功

如果不用@,可以是以下形式来表示:

def use_decorator_fun(used_for_decorator_fun):
    print("添加新功能的位置,在被装饰的函数执行之前执行")
    used_for_decorator_fun()
    print("添加新功能的位置,在被装饰的函数执行之后执行")
    return True
def used_for_decorator_fun():
    print("执行正常功能中")
    for i in range(1,11,2):
        print(i,end=',')
    print("\n执行完毕")
used_for_decorator_fun =use_decorator_fun(used_for_decorator_fun)
result = used_for_decorator_fun
if result:
    print("执行成功")
# 运行结果:
# 添加新功能的位置,在被装饰的函数执行之前执行
# 执行正常功能中
# 1,3,5,7,9,
# 执行完毕
# 添加新功能的位置,在被装饰的函数执行之后执行
# 执行成功

可以看到,@use_decorator_fun只是换成了used_for_decorator_fun =use_decorator_fun(used_for_decorator_fun),不过此句的位置换到了两个函数定义之后。

这就是装饰器的实质。

(3)装饰器传参:

被装饰的函数带有参数时,需要对装饰器函数进行处理,以便前者为后者传递参数。

此时,需要为装饰器函数增加一个嵌套函数,嵌套的内部函数带有形参列表,如果其接收参数数量确定可以直接指定好形参列表数量,但多数时候参数数量是不固定的,此时使用前文已讲述的过的两个参数*args和**kwargs来完成接收任意数量参数的要求。

例子如下:

def fun_use_add(fun_use):
    def fun_use_add_fact(a):
        print("添加新功能的位置,在被装饰的函数执行之前执行")
        fun_use(a)
        print("添加新功能的位置,在被装饰的函数执行之后执行")
        return True
    return fun_use_add_fact
@fun_use_add
def fun_use(a):
    print("执行正常功能中")
    for i in range(1,a,2):
        print(i,end=',')
    print("\n执行完毕")
result = fun_use(11)
if result:
    print("执行成功")
# 运行结果:
# 添加新功能的位置,在被装饰的函数执行之前执行
# 执行正常功能中
# 1,3,5,7,9,
# 执行完毕
# 添加新功能的位置,在被装饰的函数执行之后执行
# 执行成功

此时完成了一个参数的传递,如果参数不固定,可以改为:

def fun_use_add(fun_use):
    def fun_use_add_fact(*args,**kwargs):
        print("添加新功能的位置,在被装饰的函数执行之前执行")
        fun_use(*args,**kwargs)
        print("添加新功能的位置,在被装饰的函数执行之后执行")
        return True
    return fun_use_add_fact
@fun_use_add
def fun_use(a):
    print("执行正常功能中")
    for i in range(1,a,2):
        print(i,end=',')
    print("\n执行完毕")
result = fun_use(11)
if result:
    print("执行成功")
# 运行结果:
# 添加新功能的位置,在被装饰的函数执行之前执行
# 执行正常功能中
# 1,3,5,7,9,
# 执行完毕
# 添加新功能的位置,在被装饰的函数执行之后执行
# 执行成功
(4)带参数的装饰器:

装饰器除了接收原函数任意类型和数量的参数,还可以接收自己定义的参数。

此时,需要在装饰器函数外部额外嵌套一层函数,该层负责接收自己定义的参数,内部代码块的对应return也要添加。

同时,在@处需要在函数名后增加要传入的实参,注意,此处必须传入对应参数。

例子如下:

def fun_use_parameter(a,b):
    def fun_use_add(fun_use):
        def fun_use_add_fact(*args,**kwargs):
            print("添加新功能的位置,在被装饰的函数执行之前执行")
            for i in range(1,a+1):
                print("第"+str(i)+"次执行函数功能,函数功能序号为"+str(b))
                fun_use(*args,**kwargs)
            print("添加新功能的位置,在被装饰的函数执行之后执行")
            return True
        return fun_use_add_fact
    return fun_use_add
@fun_use_parameter(2,5)
def fun_use(a):
    print("执行正常功能中")
    for i in range(1,a,2):
        print(i,end=',')
    print("\n执行完毕")
result = fun_use(11)
if result:
    print("执行成功")
# 运行结果:
# 添加新功能的位置,在被装饰的函数执行之前执行
# 第1次执行函数功能,函数功能序号为5
# 执行正常功能中
# 1,3,5,7,9,
# 执行完毕
# 第2次执行函数功能,函数功能序号为5
# 执行正常功能中
# 1,3,5,7,9,
# 执行完毕
# 添加新功能的位置,在被装饰的函数执行之后执行
# 执行成功
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiaohei07

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值