Python类型错误'_io.TextIOWrapper'对象在从HTML获取数据时不支持项分配

2024-09-21 01:15:05 发布

您现在位置:Python中文网/ 问答频道 /正文

当使用flask从HTML获取数据并尝试用json文件中的数据创建一个新dict时

[2018-08-04 18:48:46,700] ERROR in app: Exception on /savetask [POST]
Traceback (most recent call last):
  File "C:\Users\ninja_000\AppData\Local\Programs\Python\Python36\lib\site-packages\flask\app.py", line 1982, in wsgi_app
    response = self.full_dispatch_request()
  File "C:\Users\ninja_000\AppData\Local\Programs\Python\Python36\lib\site-packages\flask\app.py", line 1614, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "C:\Users\ninja_000\AppData\Local\Programs\Python\Python36\lib\site-packages\flask\app.py", line 1517, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "C:\Users\ninja_000\AppData\Local\Programs\Python\Python36\lib\site-packages\flask\_compat.py", line 33, in reraise
    raise value
  File "C:\Users\ninja_000\AppData\Local\Programs\Python\Python36\lib\site-packages\flask\app.py", line 1612, in full_dispatch_request
    rv = self.dispatch_request()
  File "C:\Users\ninja_000\AppData\Local\Programs\Python\Python36\lib\site-packages\flask\app.py", line 1598, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "gui.py", line 33, in savetask
    task['taskid'] = str(request.form['taskid'])
TypeError: '_io.TextIOWrapper' object does not support item assignment

我的Python

^{pr2}$

我的JSON

[
    {
        "taskid": "Task 1",
        "profilename": "profile1"
    },
    {
        "taskid": "Task 2",
        "profilename": "profile2"
    }
]

非常感谢你的帮助我看了其他帖子,但我找不到答案


Tags: inpyappflasklibpackageslocalline
1条回答
网友
1楼 · 发布于 2024-09-21 01:15:05

不能只指定给打开的文件对象。打开的文件对象,即使是JSON数据,也不能充当映射,因此task['taskid'] = ...失败。在

如果文件包含JSON文档,则需要:

  • 将JSON数据解析为Python对象
  • 更新Python对象以添加新信息。在
  • 将Python对象编码为JSON并将其写回文件中。在

当你更新你的任务列表时,你可能也要弄清楚该怎么办。当任务id已经存在时应该怎么办?您需要考虑数据结构;也许列表并不适合作为一种结构,而{taskid: taskdata}字典是更新现有任务的更好方法。在

请注意,您不能这样做,支持多个并发请求来尝试相同的操作,并保持数据的一致性!例如,如果您在服务器仍在尝试编码和写入磁盘时重新加载网页,则另一个请求将看到部分数据并引发异常。在

您需要添加文件锁定来解决这一问题,或者写入一个单独的临时位置,然后移动到该位置以替换旧文件;移动操作是atomic,因为它会同时发生,任何其他同时读取文件的尝试都将获得旧版本或新版本,但始终是完整的文件。在

对于一个简单的家庭作业任务来说,可能不需要担心并发性,但是对于现实世界的web应用程序来说,这绝对是您需要处理的事情。任何服务于不止一个访问者的网站必须考虑到当两个或两个以上的访问者同时访问你的网站时可能发生的情况。在

因此,对于在多人尝试添加任务时不会立即中断的有效解决方案,您可以使用:

import os.path
import shutil
import tempfile

@app.route('/savetask', methods=['POST'])
def savetask():
    tasks_path = os.path.join(app.root_path, 'tasks/tasks.json')
    # load the JSON list
    with open(tasks_path) as tasksfile:
        tasks = json.load(tasksfile)

    # add a new task
    tasks.append({
        'taskid': request.form['taskid'],
        'profilename': request.form['profile'],
    })

    # write out the tasks to a new file, then move
    # it across to replace the old.
    with tempfile.NamedTemporaryFile(dir=os.path.dirname(tasks_path), delete=False) as temporary_file:
        json.dump(tasks, temporary_file)
    shutil.move(temporary_file.name, tasks_path)

    return redirect('/')

现在你要担心的是当两个请求同时试图添加一个任务时会发生什么。您认为这两种方法都会正确地添加到JSON文件中,还是会丢失数据?在

相关问题 更多 >

    热门问题