What is the naming convention in Python for asynchronous functions?

44 Views Asked by At

In python class, when you have to mix synchronous and asynchronous functions, what is the best practice ?

first option:

Class My_Class:
  def myfct_sync(...)
  async def myfct_async(...)

second option: prefix with a 'a' character, like __iter__ and __aiter__

Class My_Class:
  def myfct(...)
  async def amyfct(...)

third option: separate in two classes

Class My_Class:
  def myfct(...)

Class Async_My_Class:
  async def myfct(...)
1

There are 1 best solutions below

0
bmitc On

All classes in Python should be PascalCase. This is detailed in PEP 8 - Style Guide for Python. Aside from that, I am not aware of any specific asyncio naming conventions.

For asynchronous related classes, it is up to you and your code base. In a purely asyncio codebase, I don't think there is any added benefit by putting the word Async somewhere in the class names. However, in a code base where asyncio code will be mixed in with synchronous code, I think there is indeed a benefit to prefixing classes with Async. For example, say that you have a synchronous thread communicating with an asyncio event loop. Inside the event loop, you might create an Inbox class to communicate between the various coroutines and tasks running on the event loop. It makes sense to name the class AsyncInbox instead of just Inbox to make it clear that it is intended to be used inside an event loop.

For methods, that is again up to you. If you look at the core module for asyncio.Queue, there is a mix of synchronous (get_nowait, put_nowait) and asynchronous methods (get, put). For the most part, a linter for your IDE such as Pylance should make it clear enough whether a method or function returns a coroutine or not. Also, coroutines are required to use the async keyword. So generally speaking and as opposed to my recommendation for classes, I think it doesn't make much sense to add the word async into a function or method.

Where it does make sense to me is for when a class (and thus methods) or a module (and thus functions) expose two versions of a function, one synchronous and one asynchronous. In such a special case, one could consider putting _async as a suffix. But that still depends. For example, the asyncio.Queue class above doesn't do that because the get_nowait and put_nowait are effectively non-blocking functions. If they were, then naming them get_sync and put_sync OR leaving them as get and put and naming the asynchronous blocking versions as get_async and put_async would be some options.