【Python】高阶函数式编程语法糖之最佳实践


背景:Python宗旨:大道至简;不写一切不必要的代码;需足够干净、简单、纯粹。本次推荐皆是Python内置函数提供的便捷写法。

1、lambda函数

lambda函数是Python提供的语法糖,适合用于相对比较简单的函数。
lambda param_list: expression

func = lambda x:x*2
def func(x):
	return x*2

解释:以上两种写法等价;

2、map函数

map:会根据提供的函数对指定序列做映射;map(function, iterable, ...)

res = map(lambda x:x*2,[1,2,3])  # res为map函数返回的迭代器对象,故强转list做容器承接
data = list(res)
==> [2,4,6]
### 等价于
data = list(map(func,[1,2,3]))

3、reduce函数

reduce: 函数会对参数序列中元素的运行结果进行累积
reduce(function, iterable[, initializer])

reduce(lambda x,y:(x+y)*2,[1,2,3])
==>18

解释:(1+2)*2 = 6 ; (6+3)*2 = 18

4、filter条件过滤

filter:内置函数用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表
filter(function, iterable)

list(filter(lambda x: x % 2 == 0, [1,2,3,4,5,6,7,8,9,10]))
==> [[2, 1], [3, 4], [5, 3], [7, 4], [9, 0]]

5、闭包的高级应用

def get_func(a,b):
     return lambda x:ax+b
y1 = get_func(1,1)  # y1 = lambda x:1x+1
y1(1) # 结果为2  

6、列表推导式\字典推导式 + if 过滤

items = [1,2,3,4]
# 列表推导式
timp = [item+2 for item in items]
# 字典推导式
timp = {k:k*2 for k in items}
#列表推导式 + if过滤
timp = [item+2 for item in items if item > 2]

7、enumerate内置函数

对于列表:值与索引同时获取

days=['mon','tus','wed','ths','fri','sat','sun']
for i,day in enumerate(days):
	print(i,day)

8、yield:迭代器的自定义以及高级用法详解

为什么说yield是迭代器的自定义,解释如下:range是最常见的迭代器,如图它迭代了1-10的数字。那么对于range而言,迭代1-10的数据就是range函数的规则。那么如何自定义迭代器规则呢,yield就是最好的工具

for i in range(10)
def foo(start,end):
    while 1:
        res = start*3-1
        if res < end:
            yield res
            start+=1
            continue
        break
        
for i in foo(1,10):
    print(i)
==>  2 5 8

在上述例子中,我将foo函数的规则该成了 start*3 - 1。我在我另一篇博客中讲过,迭代过程的底层实质上是调用了可迭代对象的next()函数。本事例中也是一样的,假如说for循环本身不调用next函数,那么yield res后面的代码也不会被执行。若没有Python底层关于指针的设计的伙伴可以先不用去深究这个点。我在此推荐一种好用的最佳实践,关于数据库的启停:

def db_connect():
	'''数据库连接(省略)'''
	return db,cursor

def with_db():
	db,cursor = db_connect()
	try:
		yield db,cursor
	finally:
		cursor.close()
		db.close()

def service():
	db,cursor = next(with_db()#此处返回一个迭代器对象,那么调用next函数,指针将定位到db对象

在此例中,service中返回了db实例,可以往下可以执行crud相关操作,执行完毕之后with_db将最后执行db.close(),故将不必在业务代码中关心数据库的启停。小伙伴会问,为什么可以这样!事实上如我所讲yield代码片一直在等待service函数发出next()函数指令,当service发出函数指令后,yield将执行下面的代码,又因为此时service不再发出next()指令,故finally代码片一直处于等待状态。又因为finally底层的特性,注定它将在所有其他动作执行完之后执行,所以当service函数执行完之后,才执行finally中的db.close()。
如果有些经验的朋友会知道,finally的优先级可以在return之后,即函数finally可在函数return之后执行。所以用好finally这一特性,可以有更多的设计可能性

9、with上下文管理器

上面我们介绍了通过yield的特性设计了数据库的启停,其实上下文管理器也可以实现,事实上用上下文管理器实现数据库的启停将更加优雅。我将结合此事例论述上下文管理器的使用以及举例出如何通过上下文管理器更加优雅的设计数据库的启停;

def db_connect():
	'''数据库连接(省略)'''
	return db,cursor
	
class dbsession:
    def __init__(self):
        self.db,self.cursor = db_connect()

    def __enter__(self):
        return self.db,self.cursor

    def __exit__(self, exc_type, exc_value, traceback):
    	self.cursor.close()
        self.db.close()
        
def service():
	with dbsession() as db,cursor:
		pass

如上实现了一个上下文管理器,顾名思义。init初始化实例时执行数据库连接,紧接着执行enter函数,等于说实例化之后返回的参数由db,cursor接收。当with作用域的代码片结束执行之后,将执行exit函数,故实现了数据库的自动启停。
拓展说明:
1、with是Python提供的语法糖,专供类使用,因为在Python底层设计上要搭配类的enter、exit函数方能使用
2、enter、exit函数是类自带的内置函数,对于这种内置函数的继承开发,我们称为元编程–元类编程。通常这类函数是用于类在初始化时做的一些动作或进行一些高级封装时使用
3、exit函数的三个参数分别为错误类型、错误值、错误回溯记录。我们在上述函数中已经将其重写。事实上,Python本来自带精确的全局错误控制器,故exit的错误处理可忽略其错误处理,若有需要的伙伴可自行尝试

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
函数编程是一种编程,它将计算视为数学函数的求值过程。Python作为一门多范编程语言,也支持函数编程。在函数编程中,函数被视为一等公民,可以作为参数传递给其他函数,也可以作为返回值返回。函数编程强调不可变性和无副作用,通过使用纯函数来实现。 在Python中,函数编程可以通过以下几个特性来实现: 1. 高阶函数Python中的函数可以作为参数传递给其他函数,也可以作为返回值返回。这使得我们可以使用高阶函数来实现函数的组合、柯里化等功能。 2. 匿名函数Python中的lambda表达允许我们创建匿名函数,这些函数可以在需要时直接定义,而不需要使用def关键字进行命名。 3. map、filter和reduce函数:这些内置函数函数编程的重要工具。map函数可以将一个函数应用于一个可迭代对象的每个元素,并返回一个新的可迭代对象;filter函数根据指定的条件过滤可迭代对象中的元素,并返回一个新的可迭代对象;reduce函数对可迭代对象中的元素进行累积操作,返回一个单一的结果。 4. 列表推导和生成器表达:这些语法结构允许我们使用简洁的方创建新的列表或生成器,从而实现对可迭代对象的转换或筛选。 5. 不可变性:函数编程强调不可变性,即函数的参数和局部变量在函数执行期间不可修改。Python中的元组和frozenset等不可变对象可以用来实现这一特性。 6. 递归:函数编程常常使用递归来解决问题,通过函数自身调用来实现循环和迭代的效果。 总结起来,Python函数编程提供了一系列工具和语法结构,使得我们可以更加方便地使用函数作为一等公民,并且实现函数的组合、柯里化、惰性求值等特性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

会振刀的程序员

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

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

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

打赏作者

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

抵扣说明:

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

余额充值