Python Consoles for Inline Functions

I am currently using python 3.4, @coroutine decorator and the yield keyword (in a tornado) for asynchronous purposes. I wrote an ORM with many instrospection objects that call a "slow" database and override built-in functions like __init__or __contains__. My question is: For example, when my asynchronous code is in the definition of an object __contains__, how can I indirectly / transparently call it when I use the "in" operator in my tornado controller? Implicitly, because I do not want the controller-side developer to change his code when he calls the built-in functions.

+4
source share
1 answer

If I understand the question correctly, the answer is that you cannot; There is no way to write a magic method as an explicit coroutine and behave correctly if it is implicitly called Python. This is a known limitation of explicit coroutines.

So, if you have this:

class SomeObj:
    @coroutine
    def __contains__(self, obj):
        exists = yield self.somemethod(obj)
        return exists

This will not do what you want:

o = SomeObj()
'x' in o # This won't work right

Python does not expect to __contains__be a coroutine and will not behave correctly if it is - the core of the language does not know anything about tornadoor asyncio, or any other frameworks is used to implement these coroutines and will not integrate correctly with them. The same applies to other implicitly called magic methods, such as __init__, __getattr__etc.

, , yield yield from ( ). , (, , @classmethod) SomeObj, , , __init__:

@coroutine
def create_someobj():
   s = SomeObj()
   yield s.slow_init()
   return s

coroutine - contains , in. , , .

, ; PEP 492, , for-loops ( , ). , Python 3.5, :

async def some_func():  # async is used instead of a coroutine decorator
    # Assume SomeObj implements __anext__, __aiter__, __aenter__, and __aexit__
    s = SomeObj()
    async for item in s:  # You can suspend while iterating over s using __anext__
       print(item)

    async with SomeObj() as s: # You can suspend on enter and exit of this context manager using __aenter__ and __aexit__
        await s.some_method() # await is used instead of yield from
+7

All Articles