python关键字from,Python 中的 yield from 关键字

Python 3.3 新增 yield from 语法,是理解协程的基础

#0 了解一下 itertools.chain

itertools.chain() 方法可以将不同的迭代类型连接起来进行 for 循环遍历。

from itertools import chain

lst = [1,2,3]

dic = {

"tom":"www.tom.com",

"bob":"bob.com"

}

# 使用 chain 方法可以直接对三个进行 for 循环

for value in chain(lst,dic,range(5,10)):

print(value)

>>>

1

2

3

tom

bob

5

6

7

8

9

那么 itertools.chain() 是如何实现的呢?

# chain 的实现方法

# *args

# **kwargs

def chainer(*args, **kwargs):

for iterable in args:

for value in iterable:

yield value

for value in chainer(lst,dic,range(5,10)):

print(value)

>>>

1

2

3

tom

bob

5

6

7

8

9

有了 yield from之后,我们还可以进一步少些代码:

# chain 的实现方法

# *args

# **kwargs

def chainer(*args, **kwargs):

for iterable in args:

yield from iterable

for value in chainer(lst,dic,range(5,10)):

print(value)

>>>

1

2

3

tom

bob

5

6

7

8

9

看,效果其实一模一样!应该可以大致感觉到yield from的特性了吧!yield from 后面操作一个 iterable 类型的对象可以直接获取到 iterable 类型的对象的值并返回。而 yield则不一样!

#1 yield from 和 yield 的区别

def g1(iterable):

yield range(10)

for v in g1(range(10)):

print(v)

>>>

range(0, 10)

def g2(iterable):

yield from range(10)

for v in g2(range(10)):

print(v)

>>>

0

1

2

3

4

5

6

7

8

9

#2 yield from 高级特性及 Coroutine 实现

1.main 调用方,func_yield_from 委托生成器, iterable 子生成器

2.yield from 会在调用方和子生成器直接建立一个通道,双向通道,可以互相通

def func_yield_from(iterable):

yield from iterable

def main():

g = func_yield_from(range(10))

g.send(None)

看一个具体的实例:

final_result = {}

# 子生成器

def sum_sales(product_name):

total = 0

nums = []

while True:

x = yield

if x:

print(product_name + "销量:", x)

# 当 send None 的时候,跳出 while 循环

if not x:

break

total += x

nums.append(x)

return total, nums

# 委托生成器

def middle(key):

while True:

final_result[key] = yield from sum_sales(key)

print("Complete!",final_result[key])

# 调用方

def main():

dataset = {

'apple': [1200, 1330, 500],

'orange': [400, 600, 1000],

'banana': [100, 500, 50]

}

for key,dataset in dataset.items():

print('key:', key)

print('dataset:',dataset)

m = middle(key)

# 预激 middle 协程

m.send(None)

# 给协程传递每一组的值

for value in dataset:

m.send(value)

# 传递 None 终止 while 循环

m.send(None)

print(final_result)

if __name__ == "__main__":

main()

输出如下:

>>>

key: apple

dataset: [1200, 1330, 500]

apple销量: 1200

apple销量: 1330

apple销量: 500

Complete! (3030, [1200, 1330, 500])

key: orange

dataset: [400, 600, 1000]

orange销量: 400

orange销量: 600

orange销量: 1000

Complete! (2000, [400, 600, 1000])

key: banana

dataset: [100, 500, 50]

banana销量: 100

banana销量: 500

banana销量: 50

Complete! (650, [100, 500, 50])

{'apple': (3030, [1200, 1330, 500]), 'orange': (2000, [400, 600, 1000]), 'banana': (650, [100, 500, 50])}

#3 yield from 背后做的事情

try-catch 异常

# 没有 yield 的情况

def sum_sales(product_name):

total = 0

nums = []

while True:

x = yield

if x:

print(product_name + "销量:", x)

# 当 send None 的时候,跳出 while 循环

if not x:

break

total += x

nums.append(x)

return total, nums

if __name__ == "__main__":

gen = sum_sales('apple')

gen.send(None)

gen.send(1200)

gen.send(1000)

gen.send(800)

# gen.send(None)

>>>

apple销量: 1200

apple销量: 1000

apple销量: 800

去掉 gen.send(None)注释之后:

>>>

apple销量: 1200

apple销量: 1000

apple销量: 800

Traceback (most recent call last):

File "/4_yield_from_try_catch_except.py", line 27, in

gen.send(None)

StopIteration: (3000, [1200, 1000, 800])

可见抛出了一个异常,并返回了我们需要的值。所以,在没有 yield from 的情况下,我们需要捕获这个异常:

if __name__ == "__main__":

gen = sum_sales('apple')

gen.send(None)

gen.send(1200)

gen.send(1000)

gen.send(800)

try:

gen.send(None)

except StopIteration as e:

result = e.value

print(result)

这样,就能正常了,不仅不会抛出异常,还能够获取到我们需要的值了:

apple销量: 1200

apple销量: 1000

apple销量: 800

(3000, [1200, 1000, 800])

所以说,单纯不用yield from的话,我们就需要写异常处理之类的逻辑,进一步减少代码量。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
疫情居家办公系统管理系统按照操作主体分为管理员和用户。管理员的功能包括办公设备管理、部门信息管理、字典管理、公告信息管理、请假信息管理、签到信息管理、留言管理、外出报备管理、薪资管理、用户管理、公司资料管理、管理员管理。用户的功能等。该系统采用了MySQL数据库,Java语言,Spring Boot框架等技术进行编程实现。 疫情居家办公系统管理系统可以提高疫情居家办公系统信息管理问题的解决效率,优化疫情居家办公系统信息处理流程,保证疫情居家办公系统信息数据的安全,它是一个非常可靠,非常安全的应用程序。 管理员权限操作的功能包括管理公告,管理疫情居家办公系统信息,包括外出报备管理,培训管理,签到管理,薪资管理等,可以管理公告。 外出报备管理界面,管理员在外出报备管理界面可以对界面显示,可以对外出报备信息的外出报备状态进行查看,可以添加新的外出报备信息等。签到管理界面,管理员在签到管理界面查看签到种类信息,签到描述信息,新增签到信息等。公告管理界面,管理员在公告管理界面新增公告,可以删除公告。公告类型管理界面,管理员在公告类型管理界面查看公告的工作状态,可以对公告的数据进行导出,可以添加新公告的信息,可以编辑公告信息,删除公告信息
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值