python常见的几种函数:
1、普通函数
def function():
return 1
2、生成器函数
def generator():
yield 1
3、异步函数(协程)
async def async_function():
return 1
4、异步生成器
async def async_generator():
yield 1
协程需要通过其他方式来驱动,因此可以使用这个协程对象的send方法给协程发送一个值,
try:
async_function().send(None)
except StopIteration as e:
print(e.value)
#1
#通过上面的方式来新建一个run函数来驱动协程函数:
def run(coroutine):
try:
coroutine.send(None)
except StopIteration as e:
return e.value
#在协程函数中,可以通过await语法来挂起自身的协程,并等待另一个协程完成直到返回结果:
async def async_function():
print(0)
return 1
async def await_coroutine():
result = await async_function()
print(result)
run(await_coroutine())
要注意的是,await语法只能出现在通过async修饰的函数中,否则会报SyntaxError错误。
而且await后面的对象需要是一个Awaitable,或者实现了相关的协议。
查看Awaitable抽象类的代码,表明了只要一个类实现了__await__方法,那么通过它构造出来的实例就是一个Awaitable:
class Awaitable(metaclass=ABCMeta):
__slots__ = ()
@abstractmethod
def __await__(self):
yield
@classmethod
def __subclasshook__(cls, C):
if cls is Awaitable:
return _check_methods(C, "__await__")
return NotImplemented
而且可以看到,Coroutine类也继承了Awaitable,而且实现了send,throw和close方法。所以await一个调用异步函数返回的协程对象是合法的。
class Coroutine(Awaitable):
__slots__ = ()
@abstractmethod
def send(self, value):
...
@abstractmethod
def throw(self, typ, val=None, tb=None):
...
def close(self):
....
@classmethod
def __subclasshook__(cls, C):
if cls is Coroutine:
return _check_methods(C, '__await__', 'send', 'throw', 'close')
return NotImplemented