generator.throw()有什么用? [英] What is generator.throw() good for?
问题描述
PEP 342(通过增强型生成器进行协程)添加了throw()
生成器对象的方法,允许调用者在生成器内部 引发异常(就像它是由yield
表达式抛出的一样).
PEP 342 (Coroutines via Enhanced Generators) added a throw()
method to generator objects, which allows the caller to raise an exception inside the generator (as if it was thrown by the yield
expression).
我想知道此功能的用例是什么.
I am wondering what the use cases for this feature are.
推荐答案
假设我使用生成器来处理向数据库中添加信息;我使用它来存储网络接收的信息,并且通过使用生成器,我可以在每次实际接收数据时高效地执行此操作,否则可以执行其他操作.
Let's say I use a generator to handle adding information to a database; I use this to store network-received information, and by using a generator I can do this efficiently whenever I actually receive data, and do other things otherwise.
因此,我的生成器首先打开一个数据库连接,并且每次向它发送内容时,它都会添加一行:
So, my generator first opens a database connection, and every time you send it something, it'll add a row:
def add_to_database(connection_string):
db = mydatabaselibrary.connect(connection_string)
cursor = db.cursor()
while True:
row = yield
cursor.execute('INSERT INTO mytable VALUES(?, ?, ?)', row)
一切都很好,很好;每当我.send()
我的数据时,它都会插入一行.
That is all fine and well; every time I .send()
my data it'll insert a row.
但是如果我的数据库是事务性的怎么办?当将数据提交到数据库时,如何向该生成器发出信号?以及何时中止交易?而且,它保持着到数据库的开放连接,也许我有时希望它关闭该连接以回收资源.
But what if my database is transactional? How do I signal this generator when to commit the data to the database? And when to abort the transaction? Moreover, it is holding an open connection to the database, maybe I sometimes want it to close that connection to reclaim resources.
这是.throw()
方法出现的地方;使用.throw()
,我可以在该方法中引发异常以表示某些情况:
This is where the .throw()
method comes in; with .throw()
I can raise exceptions in that method to signal certain circumstances:
def add_to_database(connection_string):
db = mydatabaselibrary.connect(connection_string)
cursor = db.cursor()
try:
while True:
try:
row = yield
cursor.execute('INSERT INTO mytable VALUES(?, ?, ?)', row)
except CommitException:
cursor.execute('COMMIT')
except AbortException:
cursor.execute('ABORT')
finally:
cursor.execute('ABORT')
db.close()
生成器上的.close()
方法本质上是相同的;它结合使用GeneratorExit
异常和.throw()
来关闭正在运行的生成器.
The .close()
method on a generator does essentially the same thing; it uses the GeneratorExit
exception combined with .throw()
to close a running generator.
所有这些都是协程工作方式的重要基础;协程本质上是生成器,还有一些其他语法使编写协程更加容易和清晰.但是在幕后,它们仍然建立在相同的收益和收益上.而且,当您并行运行多个协程时,您需要一种方法,如果其中一个协程失败,则干净地退出这些协程.仅举一个例子.
All this is an important underpinning of how coroutines work; coroutines are essentially generators, together with some additional syntax to make writing a coroutine easier and clearer. But under the hood they are still built on the same yielding, and sending. And when you are running multiple coroutines in parallel, you need a way to cleanly exit those coroutines if one of them has failed, just to name an example.
这篇关于generator.throw()有什么用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!