加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

将瓶子FORMSDICT转换为Python字典(以线程安全的方式)

发布时间:2020-12-20 13:45:41 所属栏目:Python 来源:网络整理
导读:我刚刚完成了[瓶子教程[ 1并找到了以下有用的表格(我希望我的格式正确),可以访问哪些类型的请求属性 Attribute GET Form fields POST Form fields File UploadsBaseRequest.query yes no noBaseRequest.forms no yes noBaseRequest.files no no yesBaseReque
我刚刚完成了[瓶子教程[ 1并找到了以下有用的表格(我希望我的格式正确),可以访问哪些类型的请求属性

Attribute           GET Form fields     POST Form fields    File Uploads
BaseRequest.query   yes                 no                  no
BaseRequest.forms   no                  yes                 no
BaseRequest.files   no                  no                  yes
BaseRequest.params  yes                 yes                 no
BaseRequest.GET     yes                 no                  no
BaseRequest.POST    no                  yes                 yes

当然我想自己尝试一下,但是因为Bottle数据结构是特殊的线程安全版本,我想用json以合理的格式打印它,我编写了以下(工作)测试程序

from bottle import run,route,request,response,template,Bottle
import uuid
import json
import os

ondersoek = Bottle()

@ondersoek.get('/x')
@ondersoek.post('/x')
def show_everything():
   PythonDict={}
   PythonDict['forms']={}
   for item in request.forms:
      PythonDict['forms'][item]=request.forms.get(item)

   PythonDict['query']={}
   for item in request.forms:
      PythonDict['query'][item]=request.query.get(item)

   #The below does not work - multipart/form-data doesn't serialize in json
   #PythonDict['files']={}
   #for item in request.files:
      #PythonDict['files'][item]=request.files.get(item)

   PythonDict['GET']={}
   for item in request.GET:
      PythonDict['GET'][item]=request.GET.get(item)

   PythonDict['POST']={}
   for item in request.POST:
      PythonDict['POST'][item]=request.POST.get(item)

   PythonDict['params']={}
   for item in request.params:
      PythonDict['params'][item]=request.params.get(item)

   return json.dumps(PythonDict,indent=3)+"n"

ondersoek.run(host='localhost',port=8080,reloader=True)

这有效,我得到:

tahaan@Komputer:~/Projects$curl -G -d dd=dddd http://localhost:8080/x?q=qqq
{
   "files": {},"GET": {
      "q": "qqq","dd": "dddd"
   },"forms": {},"params": {
      "q": "qqq","query": {},"POST": {}
}

tahaan@Komputer:~/Projects$curl -X POST -d dd=dddd http://localhost:8080/x?q=qqq
{
   "files": {},"GET": {
      "q": "qqq"
   },"forms": {
      "dd": "dddd"
   },"query": {
      "dd": null
   },"POST": {
      "dd": "dddd"
   }
}

我非常确定这不是线程安全的,因为我将数据一次从Bottle数据结构复制到Python本机数据结构中.现在我仍在使用默认的非线程服务器,但出于性能原因,我希望在将来的某个时候使用像CherryPy这样的线程服务器.因此,问题是如何将数据从Bottle或任何其他类似的线程安全dict中转换为可以转换为JSON(轻松)的内容? Bottle是否有机会在某处暴露FormsDict-To-Json函数?

解决方法

您的代码是线程安全的.即,如果您在多线程服务器中运行它,它就可以正常工作.

这是因为多线程服务器仍然只为每个线程分配一个请求.你没有全球数据;代码中的所有数据都包含在单个请求中,这意味着它位于单个线程中.

例如,Request object的Bottle文档说(强调我的):

A thread-local subclass of
BaseRequest with a different set of attributes for each thread. There
is usually only one global instance of this class (request). If
accessed during a request/response cycle,this instance always refers
to the current request (even on a multithreaded server)
.

换句话说,每次在代码中访问请求时,Bottle都会为您提供一个“魔术”来为您提供线程本地Request对象.这个对象不是全局的;它与可能同时存在的所有其他Request对象不同,例如在其他线程中.因此,它是线程安全的.

编辑以回应您关于PythonDict的问题:此行使您的代码线程安全:

PythonDict={}

这是安全的,因为每次线程命中代码行时你都会创建一个新的dict;你创建的每个字典都是创建它的线程的本地字典. (在更多技术术语中:它在堆栈上.)

这与您的线程共享全局字典的情况形成对比;在这种情况下,你的怀疑是正确的:它不是线程安全的.但是在你的代码中,dict是本地的,因此不存在线程安全问题.

希望有所帮助!

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读