2017-06-30 51 views
2

鏈考慮下面的代碼:aiohttp:裝飾序列

from aiohttp_mako import template 

def authorize(): 
    def wrapper(func): 
     @asyncio.coroutine 
     @functools.wraps(func) 
     def wrapped(*args): 
      allowed = # Some auth stuff 
      if not allowed: 
       return HTTPUnauthorized() 
      return func() 
     return wrapped 
    return wrapper 


@authorize() 
@template('admin.mak') 
async def admin(request): 
    return dict(ok=True) 

我希望authorize()'wrapper得到template裝飾爲func 這樣我就可以回到它生成的Responseauthorize裝飾。但authorize()'wrapper採取admin()協程爲func而且因爲它試圖返回協程與

File "/Users/etemin/virtualenvs/onlinelux/lib/python3.5/site-packages/aiohttp/web.py", line 306, in _handle 
    resp = yield from handler(request) 
File "/Users/etemin/virtualenvs/onlinelux/lib/python3.5/site-packages/aiohttp_session/__init__.py", line 134, in middleware 
    raise RuntimeError("Expect response, not {!r}", type(response)) 
RuntimeError: ('Expect response, not {!r}', <class 'generator'>) 

結束。我應該如何使它返回template修飾器?

回答

3

你包裹協同例程,所以你需要等待是協同例程(收​​益率從它):既然你已經在使用async/await語法

def authorize(): 
    def wrapper(func): 
     @asyncio.coroutine 
     @functools.wraps(func) 
     def wrapped(*args): 
      allowed = # Some auth stuff 
      if not allowed: 
       return HTTPUnauthorized() 
      return yield from func() 
     return wrapped 
    return wrapper 

,我剛剛使用過這裏,而不是使用@asyncio.coroutine

def authorize(): 
    async def wrapper(func): 
     @functools.wraps(func) 
     async def wrapped(*args): 
      allowed = # Some auth stuff 
      if not allowed: 
       return HTTPUnauthorized() 
      return await func() 
     return wrapped 
    return wrapper 

請注意,我在等待func()那裏,並返回結果。

+0

謝謝你的迴應。我遇到了一些非常奇怪的事情。 'yield'語法引發了'RuntimeError:('Expect response,not {!r}',)',但同樣的'async/await'語法效果很好!怎麼來的? – Juggernaut

+1

@Juggernaut:啊,忘了'return',現在加入。對於那個很抱歉! –