【问题标题】:Can not copy an object in Python async function无法在 Python 异步函数中复制对象
【发布时间】:2019-09-20 04:32:48
【问题描述】:

我正在制作带有消息同步系统的 Python WebSocket 服务器和 HTML 客户端。 UpdateData 函数似乎没有正确复制对象。

我的 Python WebSocket 服务器代码如下

import asyncio
import json
import logging
import websockets
import copy

logging.basicConfig()

m_sysObj =\
{
    "Valve":[ 
        {
            "ActualTemp": 190,
        }
    ],
    "Test": 0
}

USERS = set()

def state_event():
    return json.dumps({"type": "state", **m_sysObj})

def users_event():
    return json.dumps({"type": "users", "count": len(USERS)})

def copyData(data):
    m_sysObj = [x[:] for x in data]

async def notify_state():
    if USERS:  # asyncio.wait doesn't accept an empty list
        message = state_event()
        await asyncio.wait([user.send(message) for user in USERS])


async def notify_users():
    if USERS:  # asyncio.wait doesn't accept an empty list
        message = users_event()
        await asyncio.wait([user.send(message) for user in USERS])


async def register(websocket):
    USERS.add(websocket)
    await notify_users()

async def unregister(websocket):
    USERS.remove(websocket)
    await notify_users()

async def updateData(websocket, path):
    # register(websocket) sends user_event() to websocket
    await register(websocket)
    try:
        await websocket.send(state_event())
        async for message in websocket:
            data = json.loads(message)
            #m_sysObj = data                                    # not working
            #m_sysObj = copy.deepcopy(data)                     # not working
            #m_sysObj = [inner_list[:] for inner_list in data]  # not working
            m_sysObj["Valve"] = data["Valve"]                   # works, but I need to copy "test" as well
            await notify_state()
    finally:
        await unregister(websocket)

start_server = websockets.serve(updateData, "localhost", 6789)

asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()

我的 HTML WebSocket 客户端代码被炸了

<html>
    <head>
        <title>WebSocket demo</title>
    </head>
    <body>
        <div class="buttons">
            <div class="update button">update Button</div>
            <div class="container">
                <form></form>
                  temp: <input id="temp" class="value" type="text"><br>
                </form>
            </div>
        </div>
        <div class="state">
            <span class="users">?</span> online
        </div>
        <script>
            var m_sysObj;
            var update = document.querySelector('.update'),
                users = document.querySelector('.users'),
                websocket = new WebSocket("ws://127.0.0.1:6789/");
            update.onclick = function (event) {
                m_sysObj.Valve[0].ActualTemp = +document.getElementById('temp').value;
                websocket.send(JSON.stringify(m_sysObj));
            }

            websocket.onmessage = function (event) {
                data = JSON.parse(event.data);
                switch (data.type) {
                    case 'state':
                        m_sysObj = data;
                        document.getElementById('temp').value = data.Valve[0].ActualTemp;
                        break;
                    case 'users':
                        users.textContent = (
                            data.count.toString() + " user" +
                            (data.count == 1 ? "" : "s"));
                        break;
                    default:
                        console.error(
                            "unsupported event", data);
                }
            };
        </script>
    </body>
</html>

deepcopy 似乎不起作用,正在重置客户端的值。复制对象的唯一方法是复制单个标签。

【问题讨论】:

  • 您是否尝试确定异步是否与此深度复制失败相关?或者说如果你从你的代码中删除所有异步,深度复制成功了吗?

标签: javascript python html asynchronous websocket


【解决方案1】:

我发现问题是带有全局变量的 python 函数。我必须用 global 关键字设置全局变量

   async for message in websocket:
            data = json.loads(message)
            global m_sysObj
            m_sysObj = data
            await notify_state()

【讨论】:

    猜你喜欢
    • 2020-06-07
    • 1970-01-01
    • 1970-01-01
    • 2017-10-23
    • 2021-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多