mirror of
https://github.com/LCTT/TranslateProject.git
synced 2024-12-23 21:20:42 +08:00
校对中
校对中
This commit is contained in:
parent
dc99a25b11
commit
0d0bb9977f
@ -57,15 +57,15 @@ def get_task():
|
||||
|
||||
```
|
||||
|
||||
相反,必须显式地传递事件循环。 这进一步要求你在库代码中显式地遍历事件循环,否则可能发生很奇怪的事情。 我不知道这种设计的思想是什么,但如果不解决这个问题(例如get_event_loop() 返回实际运行的事件循环),那么唯一有意义的其他方案是明确禁止显式事件循环传递,并要求它绑定到当前上下文(线程等)。
|
||||
相反,必须显式地传递事件循环。 这进一步要求你在库代码中显式地遍历事件循环,否则可能发生很奇怪的事情。 我不知道这种设计的思想是什么,但如果不解决这个问题(例如 get_event_loop() 返回实际运行的事件循环),那么唯一有意义的其他方案是明确禁止显式事件循环传递,并要求它绑定到当前上下文(线程等)。
|
||||
|
||||
由于事件循环策略不提供当前上下文的标识符,因此库也不可能以任何方式“索引”到当前上下文。 也没有回调函数用来监视这样的上下文的拆除,这进一步限制了实际可以开展的操作。
|
||||
|
||||
### 等待与协同
|
||||
### <ruby>等待<rt>Awaitables</rt></ruby>与<ruby>协同<rt>Coroutines</rt></ruby>
|
||||
|
||||
以我的愚见,Python最大的设计错误是过度重载迭代器。 它们现在不仅用于迭代,而且用于各种类型的协程。 Python中迭代器最大的设计错误之一是如果 StopIteration没有被捕获形成的气泡。 这可能导致非常令人沮丧的问题,其中某处的异常可能导致其他地方的生成器或协同程序中止。 这是一个长期运行的问题,基于Python的模板引擎如Jinja,必须奋力解决。 模板引擎在内部渲染为生成器,并且当由于某种原因的模板引起StopIteration时,该渲染就会在那里结束。
|
||||
以我的愚见,Python 最大的设计错误是过度重载迭代器。 它们现在不仅用于迭代,而且用于各种类型的协程。 Python 中迭代器最大的设计错误之一是如果 StopIteration 没有被捕获形成的气泡。 这可能导致非常令人沮丧的问题,其中某处的异常可能导致其他地方的生成器或协同程序中止。 这是一个长期运行的问题,基于 Python 的模板引擎如 Jinja,必须奋力解决。 模板引擎在内部渲染为生成器,并且当由于某种原因的模板引起 StopIteration时,该渲染就会在那里结束。
|
||||
|
||||
Python正在慢慢学习过度重载这个系统的教训。 首先在3.x 版本加入asyncio模块,并没有语言支持。 所以自始至终它不过仅仅是装饰器和生成器。 为了实现yield from等,StopIteration再次重载。 这导致了令人困惑的行为,像这样:
|
||||
Python 正在慢慢学习过度重载这个系统的教训。 首先在3.x 版本加入 asyncio 模块,并没有语言支持。 所以自始至终它不过仅仅是装饰器和生成器。 为了实现yield from 等,StopIteration 再次重载。 这导致了令人困惑的行为,像这样:
|
||||
|
||||
```
|
||||
>>> def foo(n):
|
||||
@ -83,23 +83,24 @@ Python正在慢慢学习过度重载这个系统的教训。 首先在3.x 版本
|
||||
|
||||
```
|
||||
|
||||
没有错误,没有警告。 只是不是你期望的行为。 这是因为从一个作为生成器的函数中返回的值实际上引发了一个带有单个参数的StopIteration,它不是由迭代器协议捕获,而只是在协程代码中处理。
|
||||
没有错误,没有警告。 只是不是你期望的行为。 这是因为从一个作为生成器的函数中返回的值实际上引发了一个带有单个参数的 StopIteration,它不是由迭代器协议捕获,而只是在协程代码中处理。
|
||||
|
||||
在3.5和3.6有很多改变,因为现在除了生成器对象我们还有协程对象。 它不是通过包装一个生成器来生成协程,而是用一个单独的对象直接创建协程。通过用给函数加async前缀来实现。 例如async def x()会产生这样的协程。 现在在3.6,将有单独的异步生成器,它通过触发AsyncStopIteration保持其独立性。 此外,对于Python 3.5和更高版本,导入新的future对象(generator_stop),如果代码在迭代步骤中触发StopIteration,它将引发RuntimeError。
|
||||
在 3.5 和 3.6 有很多改变,因为现在除了生成器对象我们还有协程对象。 它不是通过包装一个生成器来生成协程,而是用一个单独的对象直接创建协程。通过用给函数加 `async` 前缀来实现。 例如 `async def x()` 会产生这样的协程。 现在在 3.6,将有单独的异步生成器,它通过触发 AsyncStopIteration 保持其独立性。 此外,对于Python 3.5 和更高版本,导入新的 future 对象(`generator_stop`),如果代码在迭代步骤中触发 StopIteration,它将引发 RuntimeError。
|
||||
|
||||
为什么我提到这一切? 因为老的实现方式并未真的消失。 生成器仍然具有send和throw方法以及协程仍然在很大程度上表现为生成器。你需要知道这些东西,它们将在未来伴随你相当长的时间。
|
||||
为什么我提到这一切? 因为老的实现方式并未真的消失。 生成器仍然具有 send 和 throw 方法以及协程仍然在很大程度上表现为生成器。你需要知道这些东西,它们将在未来伴随你相当长的时间。
|
||||
|
||||
为了统一很多这样的重复,现在我们在Python中有更多的概念了:
|
||||
为了统一很多这样的重复,现在我们在 Python 中有更多的概念了:
|
||||
|
||||
* awaitable:具有await方法的对象。 应用于由本地协同程序和旧式协同程序以及一些其他协同程序实现。
|
||||
* awaitable:具有`__await__`方法的对象。 应用于由本地协同程序和旧式协同程序以及一些其他协同程序实现。
|
||||
* coroutinefunction:返回本地协同程序的函数。 不要与返回协程的函数混淆。
|
||||
* a coroutine: 原生的协同程序。 注意,目前为止,本文档不认为老asyncio协程是协同程序。 至少我不认为inspect.iscoroutine是协程。 尽管它被未来式/等待分支接纳。
|
||||
* a coroutine: 原生的协同程序。 注意,目前为止,当前文档不认为老 asyncio 协程是协同程序。 至少 `inspect.iscoroutine` 不认为它是协程。 尽管它被 future/awaitable 分支接纳。
|
||||
|
||||
特别令人困惑的是 asyncio.iscoroutinefunctio n和 inspect.iscoroutinefunction 正在做不同的事情,这与 inspect.iscoroutine 和 inspect.iscoroutinefunction 相同。 到得注意的是,尽管 inspect 在类型检查中不知道有关 asycnio 遗留协同功能的任何信息,但是当您检查 awaitable 状态时它显然知道它们,即使它与`__await__`不一致。
|
||||
|
||||
特别令人困惑的是asyncio.iscoroutinefunction和inspect.iscoroutinefunction正在做不同的事情,这与inspect.iscoroutine和inspect.iscoroutinefunction相同。 到得注意的是,尽管在类型检查中不知道有关asycnio遗留协同功能的任何信息,但是当您检查等待状态时它显然知道它们,即使它与await不一致。
|
||||
|
||||
### 协程包装器
|
||||
|
||||
每当你运行async def ,Python就会调用一个线程局部coroutine包装器。 它由sys.set_coroutine_wrapper设置,并且它是可以包装这些东西的一个函数。 看起来有点像如下代码:
|
||||
每当你运行 async def ,Python 就会调用一个线程局部 coroutine 包装器。 它由 sys.set_coroutine_wrapper 设置,并且它是可以包装这些东西的一个函数。 看起来有点像如下代码:
|
||||
|
||||
```
|
||||
>>> import sys
|
||||
@ -113,11 +114,11 @@ __main__:1: RuntimeWarning: coroutine 'foo' was never awaited
|
||||
|
||||
```
|
||||
|
||||
在这种情况下,我从来没有实际调用原始的函数,只是给你一个提示,说明这个函数可以做什么。 目前我只能说它总是线程局部有效,所以,如果替换事件循环策略,你需要搞清楚如何让coroutine封装在相同的上下文同步更新。创建新线程不会从父线程继承那些标识。
|
||||
在这种情况下,我从来没有实际调用原始的函数,只是给你一个提示,说明这个函数可以做什么。 目前我只能说它总是线程局部有效,所以,如果替换事件循环策略,你需要搞清楚如何让 coroutine 封装在相同的上下文同步更新。创建新线程不会从父线程继承那些标识。
|
||||
|
||||
这不要与asyncio协程包装代码混淆。
|
||||
这不要与 asyncio 协程包装代码混淆。
|
||||
|
||||
### Awaitables和Futures
|
||||
### Awaitables 和 Futures
|
||||
|
||||
有些东西是awaitables。 据我所见,以下概念被认为是awaitable:
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user