日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

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

發布時間:2025/3/21 52 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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的話,我們就需要寫異常處理之類的邏輯,進一步減少代碼量。

總結

以上是生活随笔為你收集整理的python关键字from,Python 中的 yield from 关键字的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。