Python TypeError '_io.TextIOWrapper' 对象在从 HTML 获取数据时不支持项目分配



当使用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:Usersninja_000AppDataLocalProgramsPythonPython36libsite-packagesflaskapp.py", line 1982, in wsgi_app
response = self.full_dispatch_request()
File "C:Usersninja_000AppDataLocalProgramsPythonPython36libsite-packagesflaskapp.py", line 1614, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:Usersninja_000AppDataLocalProgramsPythonPython36libsite-packagesflaskapp.py", line 1517, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "C:Usersninja_000AppDataLocalProgramsPythonPython36libsite-packagesflask_compat.py", line 33, in reraise
raise value
File "C:Usersninja_000AppDataLocalProgramsPythonPython36libsite-packagesflaskapp.py", line 1612, in full_dispatch_request
rv = self.dispatch_request()
File "C:Usersninja_000AppDataLocalProgramsPythonPython36libsite-packagesflaskapp.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

@app.route('/savetask',methods=['POST'])
def savetask():
tasks = json.load(open('tasks/tasks.json'))
with open("tasks/tasks.json", "w") as task:
task['taskid'] = str(request.form['taskid'])
task['profilename'] = str(request.form['profile'])
json.dump(task, tasks)
return redirect('/')

我的JSON

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

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

不能只分配给打开的文件对象。打开的文件对象,即使是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文件中,还是数据会丢失?

相关内容

  • 没有找到相关文章

最新更新