一般问题:
我有一个装饰程序@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)
但是,函数可以是sync
或async
,因此可以返回coroutine[Any]
如何使decoratorawait
成为函数
我的特定用例:
我有一些代码在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"""
但是,当sync=False
我使用的API生成和_login()和异步函数时。因此,decorator uplink.returns.json
会感到不安,因为它希望它包装的函数能够证明一个可以解析的响应,但它会收到一个共同例程
如何使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
有些人已经开发了自己的装饰器,可以同时使用两种功能,但我还没有发现有人修改了另一个装饰器
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
目前没有回答
相关问题 更多 >
编程相关推荐