Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在python socketio服务器中使用自定义装饰器?_Python_Python Asyncio_Flask Socketio_Python Socketio - Fatal编程技术网

如何在python socketio服务器中使用自定义装饰器?

如何在python socketio服务器中使用自定义装饰器?,python,python-asyncio,flask-socketio,python-socketio,Python,Python Asyncio,Flask Socketio,Python Socketio,我想在事件处理程序上使用一些定制的装饰器,以使处理会话更加舒适 以下是我的不带自定义装饰器的事件处理程序: @sio.event async def test(sid, data): async with sio.session(sid) as sess: room_id = sess["room_id"] print('test', room_id) await sio.emit("test", {

我想在事件处理程序上使用一些定制的装饰器,以使处理会话更加舒适

以下是我的不带自定义装饰器的事件处理程序:

@sio.event
async def test(sid, data):
    async with sio.session(sid) as sess:
        room_id = sess["room_id"]
        print('test', room_id)
        await sio.emit("test", {'msg': 'msg'}, room=room_id)

import functools


async def sess_decorator(func):
    @functools.wraps(func)
    async def wrapper(sid, data, *args, **kwargs):
        async with sio.session(sid) as sess:
            return func(sid, data, sess, *args, **kwargs)
        logger.error(f'Failed to get sess.\nsid: {sid}\ndata: {data}')

    return wrapper


@sio.event
@sess_decorator
async def test(sid, data, sess):
     room_id = sess["room_id"]
     print('test', room_id)
     await sio.emit("test", {'msg': 'msg'}, room=room_id)

Traceback (most recent call last):
  File "/home/pata/.pyenv/versions/3.7.7/envs/cartel_env/lib/python3.7/site-packages/socketio/asyncio_server.py", line 476, in _handle_event_internal
    r = await server._trigger_event(data[0], namespace, sid, *data[1:])
  File "/home/pata/.pyenv/versions/3.7.7/envs/cartel_env/lib/python3.7/site-packages/socketio/asyncio_server.py", line 504, in _trigger_event
    ret = await self.handlers[namespace][event](*args)
TypeError: test() missing 1 required positional argument: 'sess'
以下是我与custom decorator的活动:

@sio.event
async def test(sid, data):
    async with sio.session(sid) as sess:
        room_id = sess["room_id"]
        print('test', room_id)
        await sio.emit("test", {'msg': 'msg'}, room=room_id)

import functools


async def sess_decorator(func):
    @functools.wraps(func)
    async def wrapper(sid, data, *args, **kwargs):
        async with sio.session(sid) as sess:
            return func(sid, data, sess, *args, **kwargs)
        logger.error(f'Failed to get sess.\nsid: {sid}\ndata: {data}')

    return wrapper


@sio.event
@sess_decorator
async def test(sid, data, sess):
     room_id = sess["room_id"]
     print('test', room_id)
     await sio.emit("test", {'msg': 'msg'}, room=room_id)

Traceback (most recent call last):
  File "/home/pata/.pyenv/versions/3.7.7/envs/cartel_env/lib/python3.7/site-packages/socketio/asyncio_server.py", line 476, in _handle_event_internal
    r = await server._trigger_event(data[0], namespace, sid, *data[1:])
  File "/home/pata/.pyenv/versions/3.7.7/envs/cartel_env/lib/python3.7/site-packages/socketio/asyncio_server.py", line 504, in _trigger_event
    ret = await self.handlers[namespace][event](*args)
TypeError: test() missing 1 required positional argument: 'sess'
问题是在应用了
@sess\u decorator之后,事件似乎根本没有触发。如果我更改了装饰程序的顺序,在调用装饰程序之前,它会通过以下跟踪失败:

@sio.event
async def test(sid, data):
    async with sio.session(sid) as sess:
        room_id = sess["room_id"]
        print('test', room_id)
        await sio.emit("test", {'msg': 'msg'}, room=room_id)

import functools


async def sess_decorator(func):
    @functools.wraps(func)
    async def wrapper(sid, data, *args, **kwargs):
        async with sio.session(sid) as sess:
            return func(sid, data, sess, *args, **kwargs)
        logger.error(f'Failed to get sess.\nsid: {sid}\ndata: {data}')

    return wrapper


@sio.event
@sess_decorator
async def test(sid, data, sess):
     room_id = sess["room_id"]
     print('test', room_id)
     await sio.emit("test", {'msg': 'msg'}, room=room_id)

Traceback (most recent call last):
  File "/home/pata/.pyenv/versions/3.7.7/envs/cartel_env/lib/python3.7/site-packages/socketio/asyncio_server.py", line 476, in _handle_event_internal
    r = await server._trigger_event(data[0], namespace, sid, *data[1:])
  File "/home/pata/.pyenv/versions/3.7.7/envs/cartel_env/lib/python3.7/site-packages/socketio/asyncio_server.py", line 504, in _trigger_event
    ret = await self.handlers[namespace][event](*args)
TypeError: test() missing 1 required positional argument: 'sess'

似乎有一些图书馆的设计问题?有没有其他方法可以完成相同的逻辑?

在如何实现装饰器方面,您有几个错误:

@sio.event
async def test(sid, data):
    async with sio.session(sid) as sess:
        room_id = sess["room_id"]
        print('test', room_id)
        await sio.emit("test", {'msg': 'msg'}, room=room_id)

import functools


async def sess_decorator(func):
    @functools.wraps(func)
    async def wrapper(sid, data, *args, **kwargs):
        async with sio.session(sid) as sess:
            return func(sid, data, sess, *args, **kwargs)
        logger.error(f'Failed to get sess.\nsid: {sid}\ndata: {data}')

    return wrapper


@sio.event
@sess_decorator
async def test(sid, data, sess):
     room_id = sess["room_id"]
     print('test', room_id)
     await sio.emit("test", {'msg': 'msg'}, room=room_id)

Traceback (most recent call last):
  File "/home/pata/.pyenv/versions/3.7.7/envs/cartel_env/lib/python3.7/site-packages/socketio/asyncio_server.py", line 476, in _handle_event_internal
    r = await server._trigger_event(data[0], namespace, sid, *data[1:])
  File "/home/pata/.pyenv/versions/3.7.7/envs/cartel_env/lib/python3.7/site-packages/socketio/asyncio_server.py", line 504, in _trigger_event
    ret = await self.handlers[namespace][event](*args)
TypeError: test() missing 1 required positional argument: 'sess'
  • 装饰器本身不应该是异步函数
  • func
    参数是原始函数,它是一个协程,因此应该等待它
具有修复程序的装饰程序如下所示:

def sess_装饰器(func):
@functools.wrapps(func)
异步def包装(sid、数据、*args、**kwargs):
与作为sess的sio.session(sid)异步:
返回等待函数(sid、数据、sess、*args、**kwargs)
logger.error(f'无法获取sess。\n ID:{sid}\n数据:{data})
返回包装器

感谢您的回答和解释!现在它起作用了。奇怪的是python并没有提供任何回溯。