Discuss / Python / 学到day05遇到问题解决不了

学到day05遇到问题解决不了

Topic source

#1 Created at ... [Delete] [Delete and Lock User]

看廖老师的源码学习到day05,程序逻辑都看明白了,但运行app.py遇到以下问题:

页面返回如下:

500 Internal Server Error

Server got itself in trouble

控制台返回如下:

ERROR:aiohttp.server:Error handling request
Traceback (most recent call last):
  File "D:\ProgramData\anaconda3\envs\myfirstApp\Lib\site-packages\aiohttp\web_protocol.py", line 452, in _handle_request
    resp = await request_handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\ProgramData\anaconda3\envs\myfirstApp\Lib\site-packages\aiohttp\web_app.py", line 543, in _handle  
    resp = await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "D:\ProgramData\anaconda3\envs\myfirstApp\Lib\site-packages\aiohttp\web_middlewares.py", line 114, in impl
    return await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "F:\Users\hkan\Documents\VisualStudioCode\MyFirstPythonWebApp\www\app.py", line 47, in logger
    return (await handler(request))
            ^^^^^^^^^^^^^^^^^^^^^^
  File "F:\Users\hkan\Documents\VisualStudioCode\MyFirstPythonWebApp\www\app.py", line 68, in response        
    if isinstance(r, web.StreamResponse):
                  ^
UnboundLocalError: cannot access local variable 'r' where it is not associated with a value
INFO:aiohttp.access:127.0.0.1 [01/Feb/2024:11:48:57 +0800] "GET / HTTP/1.1" 500 335 "-" "Mozilla/5.0 (Windows 
NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.84 Safari/537.36 HBPC/12.1.3.306"

根据控制台返馈,锁定到app模块中的response_factory函数,如下代码:

async def response_factory(app, handler):
    async def response(request):
        logging.info('Response handler...')
        try:
            r = await handler(request)#运行到await这里程序没有等待返回值,直接运行后面的代码,这时r还没有赋值。
        except AssertionError as e:
            print(e)
        if isinstance(r, web.StreamResponse):
            return r

运行到await这里程序没有等待返回值,直接运行后面的代码,这时r还没有赋值,导致后面的isinstance(r, web.StreamResponse)判断报错。

找到具体原因是在handlers模块中有如下定义:

@get('/')
async def index(request):
    users = await User.findAll()
    return {
        '__template__': 'test.html',
        'users': users
    }

其中的get装饰器是在coroweb模块中有如下定义:

def get(path):
    '''
    Define decorator @get('/path')
    '''
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kw):
            return func(*args, **kw)
        wrapper.__method__ = 'GET'
        wrapper.__route__ = path
        return wrapper
    return decorator

根据廖老师的源码,用get装饰器给index函数设置了两个私有属性,是为了后面add_routes时可以自动完成设置。可是我遇到一个问题,由此产生,

当使用了get装饰器后,index函数做asyncio.iscoroutinefuction(index)返回为False(不使用装饰器就返回True),这就把index变成了非协程函数了,

所以在运行到 r = await handle(request)时它没有等待,直接让r裸奔了。

看到廖老师的源码中本来有以下判断和处理:

if not asyncio.iscoroutinefunction(fn) and not inspect.isgeneratorfunction(fn):
        fn = asyncio.coroutine(fn)

这里可以把fn变成coroutine函数,虽然看懂了,可我安装的python 3.11.7的asyncio库里面没有coroutine这个函数。报错如下:

Exception has occurred: AttributeError       (note: full exception trace is shown but execution is paused at: _run_module_as_main)

module 'asyncio' has no attribute 'coroutine'
  File "F:\Users\hkan\Documents\VisualStudioCode\MyFirstPythonWebApp\www\cororweb.py", line 167, in add_route
    fn = asyncio.coroutine(fn)
         ^^^^^^^^^^^^^^^^^

学习到这一步查了很多资料,分析可能的原因是asyncio新版不使用@asyncio.coroutine装饰器和yield from了,而是使用async和await定义,所以是不是把

原来的coroutine函数给优化掉了。

请有耐心看到这里的大神,动动您发财的小手,帮忙支个招呗。

有没有其它办法把普通函数直接变成coroutine函数呀?或者还有没有什么其它解决办法呀?

谢谢。

正义

#2 Created at ... [Delete] [Delete and Lock User]

500 Internal Server Error

Server got itself in trouble

我也是,到第七天这里卡住了,提示说是index不是协程函数,请问这个问题解决了吗?


  • 1

Reply