Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How should you create properties when using asyncio?

When creating a class which uses asyncio I've found myself in a situation where a property getter needs to make an io operation. Therefore the function should be a coroutine. However awaiting a property feels unusual.

Here is a minimal working of example of what I mean. The code is valid and runs.

import asyncio


class Person:
    """A class that represents a person"""

    def __init__(self, forename, surname):
        self.forename = forename
        self.surname = surname

    @property
    async def fullname(self):
        """Perform an io operation and return something.

        This could be looking something up in a database for example.        
        """
        await asyncio.sleep(0.1)
        return f"{self.forename} {self.surname}"


async def main():
    john = Person("John", "Smith")

    # Let's print out the forename here, using the standard property format
    print(john.forename)

    # When printing the full name we must instroduce an await, which feels awkward.
    print(await john.fullname)


# Start the loop and run the main function
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()

Is this the correct way of doing this?

like image 453
Jacob Tomlinson Avatar asked Mar 04 '23 10:03

Jacob Tomlinson


1 Answers

Short answer: don't do this.

Longer answer: as mentionned in pep8:

Avoid using properties for computationally expensive operations; the attribute notation makes the caller believe that access is (relatively) cheap.

So anything requiring IO is obviously not a candidate for a property. FWIW we don't only expect attributes access to be cheap, we also expect them to be safe (would you expect an attribute access to possibly raise an IOError, Database error, socket error or anything similar ?)

FWIW, you mention that "awaiting a property feels unusual" which should already answer you question. Actually and as far as I'm concerned, the mere idea of an "async property" strikes me as just totally insane - properties are (semantically) about the object's state, and I just can't make sense of the concept of "async state".

like image 80
bruno desthuilliers Avatar answered Mar 16 '23 19:03

bruno desthuilliers