Python における yield キーワードの役割: 1. 関数をジェネレーターに変更します。ジェネレーターを使用すると、システム リソースを効果的に節約し、不必要なメモリ使用を回避できます。2. コンテキスト マネージャーの定義に使用されます。3.コルーチン; 4. from と連携して、サブジェネレーターを消費してメッセージを配信するために使用される yield from を形成します。
yield の使用には、次の 4 つの一般的な状況があります。
-
1 つはジェネレーター、
要約すると、ジェネレーター内のコードは yield に達すると戻り、返される内容は yield 後の式です。次回ジェネレーターの内部コードが実行されるとき、最後の状態から継続されます。 yield キーワードを使用すると、関数をジェネレーターに簡単に変更できます。
- # 2 つ目はコンテキスト マネージャーの定義に使用されます。
- 3 つ目はコルーチン
- 4 番目は、from と連携して、yield from を形成することです。これは、サブジェネレーターを消費してメッセージを配信するために使用されます。
>>> def echo(value=None): ... print("Begin...") ... try: ... while True: ... try: ... value = (yield value) ... except Exception as e: ... value = e ... finally: ... print("Clean up!!!") ... >>> generator = echo(1) >>> print(next(generator)) Begin... 1 >>> print(next(generator)) None >>> print(generator.send(2)) 2 >>> generator.throw(TypeError, "spam") TypeError('spam') >>> generator.close() Clean up!!!上記のコードの説明は以下のとおりです:
- 最初の next(generator) を実行するとき、つまりジェネレーターを事前にアクティブ化すると、ジェネレーターは実行を開始し、Begin... 文字列を出力します。 value = (yield value) の位置に到達すると、最初に yield value を呼び出して数値 1 を生成し、その後ジェネレータは yield の位置で一時停止します。
- 2 番目の next(generator) が呼び出されると、ジェネレーターは実行を再開します。 next() を使用してジェネレーター関数を呼び出すため、value の値は None になります。インタープリター関数が値を生成するまで実行を続けると、値 None がインタープリターに返され、再び一時停止されます。
- 次に、send(2) メソッドを使用してジェネレーターの呼び出しを続けます。value は受信数値 2 を受け取り、value = (生成値) を実行し続け、数値 2 を通訳、その後一時停止します。
- その後、インタプリタは throw(TypeError, "spam") メソッドを介して再度呼び出します。ジェネレータは実行を再開し、例外をスローします。ジェネレータは例外をキャッチし、例外 TypeError を渡します。 ( 'spam') が変数 value に代入され、次にプログラムが value = (生成値) まで再度実行され、TypeError('spam') がインタプリタに返されます。
- 最後に、プログラムは close() メソッドを呼び出し、ジェネレーター関数の位置で GeneratorExit をスローします。例外がスローされ、ジェネレーターは正常に終了し、最後に対応する最も外側の try を実行します。ステートメントの最終ブランチは Clean up を出力します。
ジェネレーター
予想どおり、yield に初めて遭遇するのは間違いなくジェネレーター関数内です。ジェネレーターは、数値やその他の種類の値を継続的に生成するために使用される関数で、for ループまたは next() 関数を通じて 1 つずつ呼び出すことができます。ここで強調する必要があるのは、ジェネレーターには代入のない yield 式が含まれているため、次の 2 つの形式は同等であるということです [2]:def integers_1(): for i in range(4): yield i + 1def integers_2(): for i in range(4): value = yield i + 1ここで 2 番目の形式が強調されている理由は、Yield の方が優れているためです。 send() メソッドを介して値を送信することを理解する場合に理解されます。同時に、ジェネレーターの呼び出しによって返される値は、yield 式自体の結果値ではなく、yield キーワードの右側の式 i 1 の値であることも、より正確に説明できます。 呼び出してみましょう:
>>> for n in integers_1(): ... print(n) ... 1 2 3 4 >>> for n in integers_2(): ... print(n) ... 1 2 3 4
コンテキスト マネージャー
Python の contexlib モジュールの @contextmanager デコレーターを使用すると、コンテキストの定義に yield を使用することもできます。マネージャーの皆さん、以下は Python Tricks 本 [3] の例です。from contextlib import contextmanager @contextmanager def managed_file(name): try: f = open(name, 'w') yield f finally: f.close()デコレーターと yield キーワードを通じて上記で定義されたコンテキスト マネージャーは、次のクラスのメソッド定義と同等です:
class ManagedFile: def __init__(self, name): self.name = name def __enter__(self): self.file = open(self.name, 'w') return self.file def __exit__(self, exc_type, exc_val, exc_tb): if self.file: self.file.close()は、次のメソッドを使用して個別に呼び出すことができます:
>>> with ManagedFile('hello.txt') as f: ... f.write('hello, world!') ... f.write('bye now') >>> with managed_file('hello.txt') as f: ... f.write('hello, world!') ... f.write('bye now')
Coroutine
コルーチンの概念は美しさに満ちており、人々の作業パターンと非常に一致しています。それを完全にマスターするにはある程度の努力が必要です。しかし、マルチスレッドはコルーチンよりもはるかに多くの問題を引き起こす可能性があるため、努力する価値はあります。以下は、Python クックブック [4] の yield 式のみを使用して記述されたコルーチンの例です。from collections import deque # Two simple generator functions def countdown(n): while n > 0: print('T-minus', n) yield n -= 1 print('Blastoff!') def countup(n): x = 0 while x < n: print('Counting up', x) yield x += 1 class TaskScheduler: def __init__(self): self._task_queue = deque() def new_task(self, task): ''' Admit a newly started task to the scheduler ''' self._task_queue.append(task) def run(self): ''' Run until there are no more tasks ''' while self._task_queue: task = self._task_queue.popleft() try: # Run until the next yield statement next(task) self._task_queue.append(task) except StopIteration: # Generator is no longer executing pass # Example use sched = TaskScheduler() sched.new_task(countdown(2)) sched.new_task(countup(5)) sched.run()
运行上面的脚本,可以得到以下输出:
T-minus 2 Counting up 0 T-minus 1 Counting up 1 Blastoff! Counting up 2 Counting up 3 Counting up 4
countdown 和 countup 两个任务交替执行,主程序在执行到 countdown 函数的 yield 表达式时,暂停后将被重新附加到队列里面。然后,countup 任务从队列中取了出来,并开始执行到 yield 表达式的地方后暂停,同样将暂停后的协程附加到队列里面,接着从队列里取出最左边的任务 countdown 继续执行。重复上述过程,直到队列为空。
上面的协程可以利用 Python3.7 中的 asyncio 库改写为:
import asyncio async def countdown(n): while n > 0: print('T-minus', n) await asyncio.sleep(0) n -= 1 print('Blastoff!') async def countup(n): x = 0 while x < n: print('Counting up', x) await asyncio.sleep(0) x += 1 async def main(): await asyncio.gather(countdown(2), countup(5)) asyncio.run(main())
可以看到利用 asyncio 库编写的协程示例比用 yield 来编写的协程要优雅地多,也简单地多,更容易被人理解。
yield from
说实话,yield from 实在有点令人费解,让人摸不着头脑。yield from 更多地被用于协程,而 await 关键字的引入会大大减少 yield from 的使用频率。yield from 一方面可以迭代地消耗生成器,另一方面则建立了一条双向通道,可以让调用者和子生成器便捷地通信,并自动地处理异常,接收子生成器返回的值。下面是 Python Cookbook 书里的一个例子,用于展开嵌套的序列[5]:
from collections.abc import Iterable def flatten(items, ignore_types=(str, bytes)): for x in items: if isinstance(x, Iterable) and not isinstance(x, ignore_types): yield from flatten(x) else: yield x items = [1, 2, [3, 4, [5, 6], 7], 8] # Produces 1 2 3 4 5 6 7 8 for x in flatten(items): print(x)
而 yield from 用于建立双向通道的用法则可以参考 Fluent Python 里例子[6],这里就不详细地解释这段代码:
# BEGIN YIELD_FROM_AVERAGER from collections import namedtuple Result = namedtuple('Result', 'count average') # the subgenerator def averager(): total = 0.0 count = 0 average = None while True: term = yield if term is None: break total += term count += 1 average = total/count return Result(count, average) # the delegating generator def grouper(results, key): while True: results[key] = yield from averager() # the client code, a.k.a. the caller def main(data): results = {} for key, values in data.items(): group = grouper(results, key) next(group) for value in values: group.send(value) group.send(None) report(results) # output report def report(results): for key, result in sorted(results.items()): group, unit = key.split(';') print(f'{result.count:2} {group:5} averaging {result.average:.2f}{unit}') data = { 'girls;kg': [40.9, 38.5, 44.3, 42.2, 45.2, 41.7, 44.5, 38.0, 40.6, 44.5], 'girls;m': [1.6, 1.51, 1.4, 1.3, 1.41, 1.39, 1.33, 1.46, 1.45, 1.43], 'boys;kg': [39.0, 40.8, 43.2, 40.8, 43.1, 38.6, 41.4, 40.6, 36.3], 'boys;m': [1.38, 1.5, 1.32, 1.25, 1.37, 1.48, 1.25, 1.49, 1.46], } if __name__ == '__main__': main(data)
可能对于熟练掌握 Python 的程序员来说,yield 和 yield from 相关的语法充满了美感。但对于刚入门的我来说,除了生成器语法让我感觉到了美感,其他的语法都让我理解起来很是费解。不过还好,asyncio 库融入了 Python 的标准库里,关键字 async 和 await 的引入,将会让我们更少地在编写协程时去使用 yield 和 yield from。 但不管怎么样,yield 都是 Python 里非常特别的一个关键字,值得花时间好好掌握了解。
以上がPython におけるキーワード yield の機能は何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

Arraysinpython、特にvianumpy、arecrucialinscientificComputing fortheirefficienty andversitility.1)彼らは、fornumericaloperations、data analysis、andmachinelearning.2)numpy'simplementation incensuresfasteroperationsthanpasteroperations.3)arayableminablecickick

Pyenv、Venv、およびAnacondaを使用して、さまざまなPythonバージョンを管理できます。 1)Pyenvを使用して、複数のPythonバージョンを管理します。Pyenvをインストールし、グローバルバージョンとローカルバージョンを設定します。 2)VENVを使用して仮想環境を作成して、プロジェクトの依存関係を分離します。 3)Anacondaを使用して、データサイエンスプロジェクトでPythonバージョンを管理します。 4)システムレベルのタスク用にシステムPythonを保持します。これらのツールと戦略を通じて、Pythonのさまざまなバージョンを効果的に管理して、プロジェクトのスムーズな実行を確保できます。

numpyarrayshaveveraladvantages-averstandardpythonarrays:1)thealmuchfasterduetocベースのインプレンテーション、2)アレモレメモリ効率、特にlargedatasets、および3)それらは、拡散化された、構造化された形成術科療法、

パフォーマンスに対する配列の均一性の影響は二重です。1)均一性により、コンパイラはメモリアクセスを最適化し、パフォーマンスを改善できます。 2)しかし、タイプの多様性を制限し、それが非効率につながる可能性があります。要するに、適切なデータ構造を選択することが重要です。

craftexecutablepythonscripts、次のようになります

numpyarraysarasarebetterfornumeroperations andmulti-dimensionaldata、whilethearraymoduleissuitable forbasic、1)numpyexcelsinperformance and forlargedatasentassandcomplexoperations.2)thearraymuremememory-effictientivearientfa

NumPyArraySareBetterforHeavyNumericalComputing、whilethearrayarayismoreSuitableformemory-constrainedprojectswithsimpledatatypes.1)numpyarraysofferarays andatiledance andpeperancedatasandatassandcomplexoperations.2)thearraymoduleisuleiseightweightandmemememe-ef

ctypesallowsinging andmanipulatingc-stylearraysinpython.1)usectypestointerfacewithclibrariesforperformance.2)createc-stylearraysfornumericalcomputations.3)passarraystocfunctions foreffientientoperations.how、how、becuutiousmorymanagemation、performanceo


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

SecLists
SecLists は、セキュリティ テスターの究極の相棒です。これは、セキュリティ評価中に頻繁に使用されるさまざまな種類のリストを 1 か所にまとめたものです。 SecLists は、セキュリティ テスターが必要とする可能性のあるすべてのリストを便利に提供することで、セキュリティ テストをより効率的かつ生産的にするのに役立ちます。リストの種類には、ユーザー名、パスワード、URL、ファジング ペイロード、機密データ パターン、Web シェルなどが含まれます。テスターはこのリポジトリを新しいテスト マシンにプルするだけで、必要なあらゆる種類のリストにアクセスできるようになります。

mPDF
mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。

SublimeText3 Linux 新バージョン
SublimeText3 Linux 最新バージョン

メモ帳++7.3.1
使いやすく無料のコードエディター

DVWA
Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、

ホットトピック









