当前位置: 首页 > news >正文

python 函数式编程

1、定义

        使用多个函数解决问题,一个函数的参数作为另一个函数的参数、函数返回的也是函数。

2、函数作为参数

2.1、基本定义

        a = func01  :变量 a 现在指向 func01 函数对象;a 不是函数的返回值,而是函数对象本身。

        在函数执行内体添加另一个函数的执行方法( fun01()),也就是在这个函数执行时候带着执行另一个函数(在调用多个函数下,使用函数参数传递函数名称实现) 

例如:函数3调用函数1和函数2的两种方式

        

def func01():print("func01执行")
def func02():print("func02执行")
def func03():func01()func02()print("func03执行")
func03()
def func01():print("func01执行")
def func02():print("func02执行")
def func03(a):a()print("func03执行")
func03(func01)
func03(func02)

2.1、隐匿函数2

        变量 = lambda 形参: 方法体。

        

def func01(a,b):return a > b
print(func01(10,20))
func01 = lambda a,b:a > b
print(func01(10,20))def func02():return "2"
print(func02())func02 = lambda :"2"
print(func02())def func03():print("3")
func03()func03 = lambda :print("3")
func03()

2.2、内置高阶函数

map(函数,可迭代对象):使用隐匿函数,将可迭代对象(list01)中的值挨个赋予x,返回x的平方(冒号后);将返回值作为新的可迭代对象使用。

list01 = [0,1,2,3,4]
for i in map(lambda x:x**2,list01):print(i)

filter(函数,可迭代对象):返回x的平方满足大于5的x(冒号前);将返回值作为新的可迭代对象。

list01 = [0,1,2,3,4]
for i in filter(lambda x:x**2>5,list01):print(i)

sorted(可迭代对象, key=函数, reverse=True):获取可迭代对象的内容进行排序,关键字 key= 和reverse = (True表示从大到小),返回值为排序后的列表结果(不修改原可迭代对象)。

list01 = [0,1,2,3,4,3,2,1]
for i in sorted(list01,key=lambda x:x**2):print(i)print(''.center(30,"^"))
for i in sorted(list01,key=lambda x:x**2,reverse=True):print(i)print(list01) #[0, 1, 2, 3, 4, 3, 2, 1]

max(可迭代对象, key = 函数):根据函数获取可迭代对象的最大值。

list01 = [0,1,2,3,4,3,2,1]
z=max(list01,key=lambda x:x**2)
print(z) #4

min(可迭代对象,key = 函数):根据函数获取可迭代对象的最小值。

list01 = [0,1,2,3,4,3,2,1]
z=min(list01,key=lambda x:x**2)
print(z)#0

 3、函数作为返回值

3.1、闭包

        函数嵌套时,内部函数调用外部函数变量(nonlocal),外部函数返回值时内部函数的名称。

def home(money):def child_buy(obj, m):nonlocal moneyif money > m:money -= mprint('买', obj, '花了', m, '元, 剩余', money, '元')else:print("买", obj, '失败')return child_buy
cb = home(1000)
cb('变形金刚', 200)

 3.2、装饰器

        在原函数基础上添加或修改功能,定义一个闭包和一个普通函数,将闭包最外层函数的名称加上@放在普通函数上

        

def mydeco(fn): #装饰函数的参数传入的被装饰函数名称fn() #执行被装饰函数 在函数体内任意一行皆可print("装饰器函数被调用了,并返回了fx") def fx(): #内层函数print("fx被调用了")# return fn()return fx #返回内层函数名称@ mydeco #将闭包最外层的函数名称放在普通函数头上 也就是说@后面是装饰函数,下面是被装饰函数
def myfun():print("函数myfun被调用")myfun()
# 函数myfun被调用
# 装饰器函数被调用了,并返回了fx
# fx被调用了

 3.2.1、基本装饰器

        被装饰函数无参数和普通调用被装饰函数的方式(一个闭包,一个无参数函数)。

def mydeco(fn):def fx():ret = fn()return fx
@mydeco
def myfunc():print("myfunc被调用.")myfunc()

 3.2.2、带参数的装饰器

        第一种:循环调用

        循环调用此函数,此时需要在装饰函数外嵌套一层(装饰器工厂函数 ),此函数的参数就是设置的循环调用变量;此函数的返回值是装饰函数;

        装饰位置的写法为 @装饰器工厂函数名称(参数)。

def repeat(num):##装饰器工厂函数 num 存储的 3def decorator(func):#装饰函数def wrapper(*args, **kwargs):for _ in range(num):func(*args, **kwargs)return wrapperreturn decorator@repeat(3)  # 应用装饰器,重复执行下面的函数3次
def greet():#被装饰函数print(f"Hello!")greet()  # 调用被装饰的函数
# Hello!
# Hello!
# Hello!

         第二种:被装饰函数有参数

        装饰函数的内嵌函数定义参数接收被装饰函数的变量(一般采用 *args 和 **args)。

        

def repeat(num):#装饰器工厂函数def decorator(func):#装饰函数def wrapper(*args, **kwargs):#内层函数接收被装饰函数的参数 存放的worldfor _ in range(num):func(*args, **kwargs) #执行被装饰函数return wrapperreturn decorator@repeat(3)  # 应用装饰器,重复执行下面的函数3次
def greet(a):#被装饰函数print(f"Hello,{a}!")greet('world')  # 调用被装饰的函数
# Hello,world!
# Hello,world!
# Hello,world!

 3.2.3、装饰器链

         像链子一样多节,在被装饰函数上存在多个装饰,按照从上到下的顺序进行执行装饰函数。

def mydeco1(fn):def fx():print("先执行第一个装饰函数")fn()return fxdef mydeco2(fn):def fx():print("先执行第二个装饰函数")fn()return fx
@mydeco1
@mydeco2
def myfunc():print("myfunc被调用.")myfunc()
# 先执行第一个装饰函数
# 先执行第二个装饰函数
# myfunc被调用.

3.2.4、类装饰器

        将装饰函数变成类,原装饰函数的参数作为实例变量;重写一个__call__的函数,等同于装饰函数的内嵌函数。

class MyDecorator:def __init__(self, func):self.func = funcdef __call__(self):print("还没执行")result = self.func()print("已经执行")return result@MyDecorator  # 应用类装饰器
def say_hello():print(f"Hello!")say_hello()  # 调用被装饰的函数


http://www.mrgr.cn/news/54904.html

相关文章:

  • Rust小练习,编写井字棋
  • 利用 PyTorch 进行深度学习训练过程中模型的 .eval() 和 .train() 属性介绍
  • VSCode编译器改为中文
  • OpenGL、OpenCL 和 OpenAL 定义及用途
  • freertos的任务管理
  • React综合指南(二)
  • 死锁的具体案例分析
  • 集合框架14:TreeSet概述、TreeSet使用、Comparator接口及举例
  • 基于深度学习的地形分类与变化检测
  • 快速学会一个算法:Faster R-CNN进行目标检测!
  • leetcode day1
  • resnetv1骨干
  • 轮班管理新策略,提高效率与降低员工抱怨
  • Vue3中使用自定义指令实现后台管理系统中对于按钮权限的控制
  • 五年三次冲刺IPO失败,企业业绩成长性恐不足,三年分红约1.5亿元
  • 对比迁移项目的改动
  • 值得收藏学习的人工智能学习框架!
  • 【重学 MySQL】七十三、灵活操控视图数据,轻松掌握视图删除技巧
  • DFF对比
  • SpringBoot运维
  • FHQtreap新模板
  • 诊断知识:NRC78(Response Pending)的回复时刻
  • @RequestMapping(“/api/users“)详细解释一下这行代码
  • 【云从】八、HTTPS流程与建站
  • Redux (八) 路由React-router、嵌套路由、路由传参、路由懒加载
  • 【Android】浅析OkHttp(1)