Har*_*rvs 5 python api async-await python-asyncio
通用问题:
我有一个装饰器@some_package.decorator
期望函数包装为返回类型T
。
### runs
@some_package.decorator
def my_func(param) -> int:
return len(param)
### I also want to be able to wrap an async function
@some_package.decorator
async def my_func(param):
await asyncio.sleep(1)
return len(param)
Run Code Online (Sandbox Code Playgroud)
然而,该函数可以是sync
or async
,因此可能返回coroutine[Any]
。
我怎样才能使装饰器await
具有功能
我的具体用例:我有一些代码在以下情况下运行良好sync=True
import uplink
class MyAPI(Consumer):
def __init__(
self,
password: str,
sync: bool = True,
auto_auth: bool = True,
**kwargs
):
self.sync = sync
self.client = None
if not self.sync:
self.client = AiohttpClient()
# initialise the super class
super(GLinet, self).__init__(client=self.client, **kwargs)
if auto_auth:
self._login(password)
@uplink.returns.json(key="token")
@uplink.post("router/login")
def _login(self, pwd: uplink.Field):
"""fetches token"""
Run Code Online (Sandbox Code Playgroud)
然而,当sync=False
我使用的 API 使得 _login() 和 async 函数。因此,装饰器uplink.returns.json
会感到不安,因为它期望它包装的函数能够证明可以解析的响应,但它却收到了一个 co 例程。
如何使uplink.returns.json
接受成为异步函数并等待它可以解析的返回值。
我尝试过这样的事情
def dec(fn):
if asyncio.iscoroutinefunction(fn):
@returns.json
async def wrapper(*args, **kwargs):
print("wrapping async function")
print(fn)
return await fn()
return wrapper
else:
@returns.json
def wrapper(*args, **kwargs):
print("wrapping sync function")
print(fn)
return fn()
return wrapper
Run Code Online (Sandbox Code Playgroud)
有些人开发了自己的装饰器,可以接受两种类型的功能,但我还没有发现有人修改过另一个装饰器
def dec(fn):
if asyncio.iscoroutinefunction(fn):
@wraps(fn)
async def wrapper(*args, **kwargs):
print(fn, args, kwargs) # <function foo at 0x10952d598> () {}
await asyncio.sleep(5)
print("done with wrapper, going to call fn")
return await fn()
return wrapper
else:
@wraps(fn)
def wrapper(*args, **kwargs):
print(fn, args, kwargs) # <function bar at 0x108fb5a60> () {}
time.sleep(5)
print("done with wrapper, going to call fn")
return fn()
return wrapper
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2506 次 |
最近记录: |