我一直在尝试理解异步编程,尤其是 Python 中的异步编程。我知道 asyncio 是基于事件循环构建的,该事件循环安排协程的执行,但我已经阅读了几种定义协程的不同方法,并且我很困惑它们如何相互关联。
I read 本文 http://masnun.com/2015/11/13/python-generators-coroutines-native-coroutines-and-async-await.html有关该主题的更多背景信息。尽管它涵盖了我提到的四种协程中的每一种,但它并没有完全描述它们的不同之处。无需任何外部模块,可以使用以下命令创建协程yield
作为等号右边的表达式,然后可以通过.send()
。但是,使用的代码示例@asyncio.coroutine
and @types.coroutine
装饰者从来不使用.send()
从我发现的情况来看。文章中的代码示例如下:
# Coroutine using yield as an expression
def coro():
hello = yield "Hello"
yield hello
c = coro()
print(next(c), end=" ")
print(c.send("World")) # Outputs Hello World
# Asyncio generator-based coroutine
@asyncio.coroutine
def display_date(num, loop):
end_time = loop.time() + 50.0
while True:
print("Loop: {} Time: {}".format(num, datetime.datetime.now()))
if (loop.time() + 1.0) >= end_time:
break
yield from asyncio.sleep(random.randint(0, 5))
# Types generator-based coroutine
@types.coroutine
def my_sleep_func():
yield from asyncio.sleep(random.randint(0, 5))
# Native coroutine in Python 3.5+
async def display_date(num, loop, ):
end_time = loop.time() + 50.0
while True:
print("Loop: {} Time: {}".format(num, datetime.datetime.now()))
if (loop.time() + 1.0) >= end_time:
break
await asyncio.sleep(random.randint(0, 5))
我的问题是:
- 怎样做
yield
协程涉及到types
or asyncio
装饰协程,哪里是.send()
使用的功能?
- 装饰器向未装饰的基于生成器的协程添加了哪些功能?
- 怎样做
@asyncio.coroutine
and @types.coroutine
装饰器不同?我读这个答案 https://stackoverflow.com/questions/39637675/what-is-the-difference-between-types-coroutine-and-asyncio-coroutine-decorator尝试理解这一点,但这里提到的唯一区别是types
如果协程没有yield 语句,那么它会像子例程一样执行。还有什么其他的吗?
- 这些基于生成器的协程在功能和实现上与最新的原生协程有何不同
async/await
协程?
你可能会笑,我看了一下源代码asyncio.coroutine https://github.com/python/cpython/blob/master/Lib/asyncio/coroutines.py#L105并发现it uses types.coroutine
(任何评论#!>
是我添加的)
def coroutine(func):
"""Decorator to mark coroutines...."""
#!> so clearly the async def is preferred.
warnings.warn('"@coroutine" decorator is deprecated since Python 3.8, use "async def" instead',
DeprecationWarning,
stacklevel=2)
if inspect.iscoroutinefunction(func):
#!> since 3.5 clearly this is returning something functionally identical to async def.
# In Python 3.5 that's all we need to do for coroutines
# defined with "async def".
return func
if inspect.isgeneratorfunction(func):
coro = func
else:
#!> omitted, makes a wrapper around a non generator function.
#!> USES types.coroutine !!!!
coro = types.coroutine(coro)
if not _DEBUG:
wrapper = coro
else:
#!> omitted, another wrapper for better error logging.
wrapper._is_coroutine = _is_coroutine # For iscoroutinefunction().
return wrapper
所以我认为这只能归结为历史问题asyncio
存在时间长于types
所以最初的处理是在这里完成的,然后当类型出现时,真正的包装器被移到那里,而 asyncio 继续只有一些额外的包装东西。但归根结底,两者都只是模仿async def
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)