How to create a Python decorator that can wrap either coroutine or function?

前端 未结 2 1751
挽巷
挽巷 2020-12-30 06:28

I am trying to make a decorator to wrap either coroutines or functions.

The first thing I tried was a simple duplicate code in wrappers:



        
2条回答
  •  长情又很酷
    2020-12-30 07:12

    May be you can find better way to do it, but, for example, you can just move your wrapping logic to some context manager to prevent code duplication:

    import asyncio
    import functools
    import time
    from contextlib import contextmanager
    
    
    def duration(func):
        @contextmanager
        def wrapping_logic():
            start_ts = time.time()
            yield
            dur = time.time() - start_ts
            print('{} took {:.2} seconds'.format(func.__name__, dur))
    
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            if not asyncio.iscoroutinefunction(func):
                with wrapping_logic():
                    return func(*args, **kwargs)
            else:
                async def tmp():
                    with wrapping_logic():
                        return (await func(*args, **kwargs))
                return tmp()
        return wrapper
    

提交回复
热议问题