Async and await features for Python 3.5 (PEP492 translation)

Source: Internet
Author: User


Reason:

1,coroutine easily confused with normal generators.

2, whether a function is Coroutine is determined by whether there is yield or yield from the body, which is unscientific.

3, if the yield is syntactically allowed in the place to make asynchronous calls, such as with and for statements can not be executed asynchronously.

How to solve, the coroutine as a native Python language features, and generator completely independent.

Native Coroutines and its new syntax make it possible (i.e. with and for) to define context Manager (context Manager) and iteration protocols (iterator Protocol) under asynchronous conditions.

The async with statement allows the Python program to execute an asynchronous call when entering and exiting the runtime context (run-time contexts);

An async for statement makes it possible to execute an asynchronous call in an iterator. (Foreigner really, always make it possible).

Syntax definitions

Suppose you already know:

* Implementation of coroutines in Python. Implementation of Coroutines in Python (PEP 342 and Pep 380).

* Some grammars to be changed come from the Asyncio framework and the "Cofunctions" offer (already tragic). Motivation for the syntax changes proposed here comes from the Asyncio framework (PEP 3156) and the "Cofunctions" propos Al (PEP 3152, now rejected in favor of this specification).

The newly defined Coroutine
Async def read_data (db): Pass

Key features of the native Couroutines:

* Functions defined with async def always native coroutine, regardless of whether there is an await expression.

* yield and yield from are not allowed in the async function and will throw a Syntaxerro exception.

* Inside, two new code object flags were introduced.

--Co_coroutine is used to mark native corroutine (i.e. defined by async def)

--The generator-based coroutine used by Co_iterable_coroutine is compatible with native coroutines.

All Coroutine objects have a co_generator standard.

* Generator Returns Generator object, Coroutines returns Coroutine object

* Coroutine with no await on will throw runtimewarning in GC.

An await expression

An await expression is used to get the execution result of a coroutine.

Async def read_data (db): data = await db.fetch (' SELECT ... ') ...

An await, similar to the yield from (in fact, does not know much), will block the execution of Read_data until the completion of Db.fetch this awaitable and return data.

Awaitable (Note: The main awaitable is a noun, not an adjective) can be:

1, the native Coroutine object returned from a native Coroutine function.

2, the Generator-based Coroutine object returned by the types.coroutine decorated (decorated) generator function.

3, an object that returns an iterator to the __await__ method of the object.

If __await__ returns a not iterator, the TypeError is thrown.

The 4,cpython C API defines the Tp_as_async->am_await function.

If an await appears outside of the async def function, the syntax Error is thrown;

Passing anything other than the Awaitable object to an await expression throws typeerror.

。。。。。。。。。

... Ignoring the strict syntax definition section ...

。。。。。。。。

The await expression takes precedence over * *, lower than slice [], function call (), and attribute reference (property reference, such as X.attribute).


Asynchronous Context Managers and "Async with"

Asynchronous Context Manager (asynchronous context Manager) is a contextual manager that can block (the current coroutine) execution in the Enter and exit methods. Added two magic functions: __aenter__ and __aexit__, and two functions must return a Awaitable object.

As an example:

Class Asynccontextmanager:async def __aenter__ (self): await log (' entering context '), async def __aexit__ (self , Exc_type, exc, TB): await log (' exiting context ')
The new syntax:

Propose a new syntax definition for the asynchronous context Manager:

Async with EXPR as Var:block

is syntactically equivalent to:

MGR = (EXPR) aexit = Type (mgr). __aexit__aenter = Type (mgr). __aenter__ (mgr) exc = Truevar = await aentertry:blockexcept: If not await aexit (Mgr, *sys.exc_info ()): Raiseelse:await aexit (Mgr, none, none, none)

As with the usual with statement, you can specify multiple context managers in an await with statement.

Example

Using the asynchronous context Manager makes it easy to implement coroutine for the database transaction manager.

With asynchronous context managers it's easy-to-implement proper database transaction managers for Coroutines:

Async Def commit (Session, data): ... async with session.transaction (): ... await session.update (data) ...

The code that needs to be locked becomes clearer: codes that needs locking also looks lighter:

Async with Lock: ...

Instead of:

With (yield from lock): ...

Asynchronous iterators and "Async for"

Asynchronous iterable can invoke asynchronous code in its ITER implementation and be able to invoke asynchronous code in its next method.

* The __aiter__ method must be implemented, the method returns a awaitable, and the result of the awaitable must be a asynchronous iterator object. An object must implement an __aiter__ method returning a awaitable resulting in an asynchronous iterator object .

* Asynchronous iterator object must implement the __ANEXT__ member function, which returns awaitable objects;

* To stop the iteration, __anext__ must throw a stopasynciteration exception.

As an example:

Class Asynciterable:async def __aiter__ (self): return self, async def __anext__ (self): data = await SE Lf.fetch_data () If Data:return data else:raise stopasynciteration Async def Fetch _data (self): ...
New syntax

A New statement for iterating through asynchronous iterators are proposed:

Async for TARGET in ITER:BLOCKelse:BLOCK2

Equivalent to:

iter = (iter) iter = await type (ITER). __AITER__ (iter) running = truewhile Running:try:TARGET = await type (ITER). __ANEXT__ (iter) except stopasynciteration:running = False else:BLOCKelse:BLOCK2

If the async for iterator does not have a __AITER__ member function, the TypeError will be thrown;

If you use async for outside of the async def function, the SyntaxError error will be thrown.

As with the usual for statement, Async for also has an optional else clause.


Async and await features for Python 3.5 (PEP492 translation)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.