之前我们介绍了tornado 的基础流程,但是还遗留了一些问题,今天我们就来解决这些遗留问题并学习新的内容

settings,使用tornado.web.Application(handler, **settings),我们却不知道这个settings到底是什么,究竟有什么作用,今天就来介绍一下。

settings是一个字典,主要保存一些配置选项

  • debug

    1. 设置tornado是否在调试模式下,默认为False,即在生产模式下。
    2. debug设置为True的生活,具有如下特点:
    3.     自动重启,tornado应用会监控源代码文件,当有保存改动时便会自动重启服务器,类似于Django,可以减少手动重启的次数,提高开发效率,如果保存代码后有错误会导致重启失败,修改错误需要手动重启,可以通过autoreload = True设置
    4.     取消缓存编译的模板:有时候我们明明修改了模板文件,但是页面显示的内容并没有变化,就是因为用的还是缓存文件。因此debug = True,可以保证每次加载的模板文件都是最新的,也可以通过compiled_template_cache=False单独设置,表示不使用已经编译好的模板缓存
    5.     取消缓存静态文件的hash值:这和取消编译模板是类似的,有时候我们修改css,但是页面颜色或者字体并没有发生变化。 有了debug=True,可以保证每次加载的静态文件都是最新的,也可以通过static_hash_cache=False单独设置,表示不使用静态文件的哈希缓存
    6.     提供追踪信息:可以通过server_traceback=True单独设置

    从源码也能看出来

  • static_path

    1. 设置静态文件目录,
    2. 注意:寻找静态文件是tornado去找,类似Django,你要告诉tornado要去什么地方去找静态文件
  • template_path

    1. 设置模板文件目录,和设置静态文件目录类似

配置文件如下:

  1. import os
  2. options = {"port": 7777}
  3. BASE_DIR = os.path.dirname(os.path.abspath(__file__))
  4. settings = {"static_path": os.path.join(BASE_DIR, "static"),
  5. "template_path": os.path.join(BASE_DIR, "templates"),
  6. "compiled_static_cache": True,
  7. "compiled_template_cache": True,
  8. "server_traceback": True}
  1. 关于静态文件路径和模板文件路径,再次强调,是tornado去找。而且后面还会用到模板语言,必须要让tornado知道相应的路径在哪里。
  2. settings中指定static_pathtemplate_path,那么tornado便会到相应的路径下去寻找。 

下面介绍一下tornado的路由,路由在上一章我们知道,是用来指定url和handler之间的映射关系。当一个url过来会进行解析,然后执行对应的handler,tornado的路由还可以加一些别的参数

view.py

  1. import tornado.web
  2. class SatoriHandler(tornado.web.RequestHandler):
  3. # 该方法会在执行http方法之前执行
  4. # 可以传入参数,这个参数则是我们在定义路由的时候指定
  5. def initialize(self, girl1, girl2):
  6. self.girl1 = girl1
  7. self.girl2 = girl2
  8. def get(self, *args, **kwargs):
  9. print(self.girl1, self.girl2)
  10. self.write("my name is satori")
  11. class MashiroHandler(tornado.web.RequestHandler):
  12. def get(self, *args, **kwargs):
  13. # url的反向解析
  14. # 我们在定义路由的时候可以指定一个name="xxx",那么self.reverse_url(name),便会获取相应的url
  15. # 这便是url的反向解析,通过指定的name获取定义的url
  16. url = self.reverse_url("satori")
  17. self.write(f'<h1><a href="{url}">还是喜欢satori</a></h1>')

application.py

  1. import tornado.web
  2. from views import view
  3. import config
  4. # 我们可以自定义一个Application,但是要继承tornado.web下的Application
  5. class Application(tornado.web.Application):
  6. def __init__(self):
  7. handlers = [
  8. # 我们在SatoriHandler的initialize中定义了girl1和girl2
  9. # 那么girl1和girl2就在包含相应handler的路由中定义
  10. # 以字典的形式传值即可
  11. (r"/satori", view.SatoriHandler, {"girl1": "satori", "girl2": "koishi"}),
  12. # 由于我们指定了name,那么name也要在包含相应handler的路由中定义
  13. # 但是name比较特殊,我们不能用一般的路由定义,要使用tornado.web.url()
  14. # 然后使用self.reverse_url(name)获取到的便是name所在路由的url
  15. # 那么在页面渲染出来的便是一个a标签
  16. tornado.web.url(r"/koishi", view.SatoriHandler, {"girl1": "satori", "girl2": "koishi"},
  17. name=r"satori"),
  18. (r"/mashiro", view.MashiroHandler)
  19. ]
  20. super(Application, self).__init__(handlers=handlers, **config.settings)

输入localhost:7777/satori,得到页面如下

同时在pycharm中也打印了girl1和girl2的值

同时在pycharm中也打印了girl1和girl2的值

两个url的handler是一样的

最后再来输入localhost:7777/mashiro,也显示了相应的字符串,而且是一个被渲染为一个a标签,我们点击一下

  1. 又跳转回去了,因为name="satori"所在路由的urlr"/koishi",那么通过在MashiroHandler中进行反向解析获取到的url就是r"/koishi"
  2. 那么点击之后会再次跳转到localhost:7777/koishi,从而执行SatoriHandler
  3. 从而在pycharm中再次输出,总共三次

利用http协议向服务器传递参数

1.提取url当中的特定部分

application.py

  1. import tornado.web
  2. from views import view
  3. import config
  4. # 我们可以自定义一个Application,但是要继承tornado.web下的Application
  5. class Application(tornado.web.Application):
  6. def __init__(self):
  7. handlers = [
  8. # 可以支持正则表达式,我们定义了三个分组
  9. # 那么用户输入的内容会根据分组依次对应传到handler的get函数里面
  10. (r"/satori/(\w+)/(\w+)/(\w+)", view.SatoriHandler),
  11. # 由于我们指定了分组的名字,就类似于关键字参数
  12. # adj1、adj2、adj3会分别对应get函数里面的adj1、adj2、adj3
  13. (r"/mashiro/(?P<adj1>\w+)/(?P<adj2>\w+)/(?P<adj3>\w+)", view.MashiroHandler)
  14. ]
  15. super(Application, self).__init__(handlers=handlers, **config.settings)

view.py

  1. import tornado.web
  2. class SatoriHandler(tornado.web.RequestHandler):
  3. def get(self, adj1, adj2, adj3):
  4. # 这里的参数会和分组的顺序保持一致
  5. self.write(f"<h1>satori {adj1}, {adj2}, {adj3}</h1>")
  6. class MashiroHandler(tornado.web.RequestHandler):
  7. def get(self, adj2, adj3, adj1):
  8. # 由于在路由中指定了名称,那么函数中参数的顺序便无所谓了
  9. self.write(f"<h1>mashiro {adj1}, {adj2}, {adj3}</h1>")

在浏览器中输入满足路由映射的url,会发现按照顺序依次打印了出来

再来试试另一个路由

  1. 可以看到即便我们在MashiroHandler中定义的参数没有什么顺序,但是在页面中依旧按照我们输入url的顺序打印了出来,
  2. 这是因为我们定义路由的时候指定了名字,那么在执行get函数的时候,相当于adj1="elegant", adj2="beautiful", adj3="cute",

2.get方式传递参数

  1. 当我们输入localhost:7777/satori?a=1&b=2&c=3的时候,可以在程序当中获取相应的a,b,c的值。
  2. 可以回想一下requestsrequests.get函数中有一个params参数,传入{"a": 1, "b": 2, "c": 3},便会自动和请求的url进行组合,从而得到类似于上面的新的url
  3. 那么反过来获取相应的a,b,c的值也是可以的

application.py

  1. import tornado.web
  2. from views import view
  3. import config
  4. # 我们可以自定义一个Application,但是要继承tornado.web下的Application
  5. class Application(tornado.web.Application):
  6. def __init__(self):
  7. handlers = [
  8. (r"/satori", view.SatoriHandler),
  9. ]
  10. super(Application, self).__init__(handlers=handlers, **config.settings)

view.py

  1. import tornado.web
  2. class SatoriHandler(tornado.web.RequestHandler):
  3. def get(self):
  4. '''
  5. 函数的原型是self.get_argument(name, strip=True)
  6. 其实这个函数是self.get_query_argument(用于获取get请求的参数)和self.get_body_argument(用于获取post请求的参数)两个的函数的组合
  7. 而self.get_argument既可以用于get也可以用于post,因此我们一般都使用self.get_argument
  8. 参数:
  9. name:返回get请求参数字符串中指定参数的值
  10. 如果出现多个同名参数,返回最后一个
  11. strip:是否过滤掉两边的空格,默认为True表示过滤
  12. '''
  13. a = self.get_argument("a")
  14. b = self.get_argument("b")
  15. c = self.get_argument("c")
  16. d = self.get_arguments("d")
  17. self.write(f"参数a={a}, 参数b={b}, 参数c={c}, 参数d={d}")

  1. 首先a,b无需解释,至于c,由于我们是self.get_argument,所以只会获取最后一个,但是对于d,使用self.get_arguments,会获取一个列表,如果只有一个值,获取的仍是个列表,列表只有一个元素

3.post方式传递参数

首先templates目录里面创建一个html文件 ,satori.html

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>古明地觉</title>
  6. </head>
  7. <body>
  8. <form action="/satori" method="post">
  9. 姓名:<input type="text" name="name">
  10. <p></p>
  11. 性别:<input type="text" name="gender">
  12. <p></p>
  13. 登场:<input type="text" name="from">
  14. <p></p>
  15. 昵称:
  16. <input type="checkbox" name="nickname" value="少女觉">少女觉
  17. <input type="checkbox" name="nickname" value="觉大人">觉大人
  18. <input type="checkbox" name="nickname" value="小五">小五
  19. <input type="submit" value="提交">
  20. </form>
  21. </body>
  22. </html>

application.py

  1. import tornado.web
  2. from views import view
  3. import config
  4. # 我们可以自定义一个Application,但是要继承tornado.web下的Application
  5. class Application(tornado.web.Application):
  6. def __init__(self):
  7. handlers = [
  8. (r"/satori", view.SatoriHandler),
  9. ]
  10. super(Application, self).__init__(handlers=handlers, **config.settings)

view.py

  1. import tornado.web
  2. class SatoriHandler(tornado.web.RequestHandler):
  3. def get(self):
  4. # self.write表示写入字符串
  5. # self.render表示将一个模板读取进来,进行渲染(替换掉模板语言),返回给用户
  6. # 而且我们只是指定了文件名,tornado居然能找得到,因为我们在settings中定义了template_path
  7. # 因此在执行self.render的时候tornado会自动到相应目录下去寻找模板文件
  8. self.render("satori.html")
  9. def post(self, *args, **kwargs):
  10. # 我们在表单中定义了name="xxx"
  11. # 因此self.get_argument的参数就是name
  12. gender = self.get_argument("gender")
  13. name = self.get_argument("name")
  14. _from = self.get_argument("from")
  15. nickname = self.get_arguments("nickname")
  16. self.write(f"你的名字是{name}, 性别是{gender}, 来自于{_from}, 昵称是{' '.join(nickname)}") 

浏览器中输入如下:

点击提交之后

HTTPServerRequest对象

  1. 想一下我们使用requests模块访问得到的response一样,这个response是服务端给我们返回的信息,如果加上了request表示客户端向服务端请求时的信息
  2. 因此request:请求,response:响应
  3. 所以tornadorequest作用就是储存了请求的相关信息
  • method:http请求的方式
  • host:请求的主机名
  • uri:请求的完整资源地址,包括路径和get参数查询部分,注意是uri不是url
  • path:请求的路径部分
  • query:请求参数部分
  • version:使用的http版本
  • headers:请求的协议头是一个字典类型
  • body:请求体数据
  • remote_ip:客户端ip

view.py,其他的文件不变

  1. import tornado.web
  2. class SatoriHandler(tornado.web.RequestHandler):
  3. def get(self):
  4. self.write("<h1>请求的信息如下:</h1>")
  5. self.write(f"<h2>self.request.method={self.request.method}</h2>")
  6. self.write(f"<h2>self.request.host={self.request.host}</h2>")
  7. self.write(f"<h2>self.request.uri={self.request.url}</h2>")
  8. self.write(f"<h2>self.request.path={self.request.path}</h2>")
  9. self.write(f"<h2>self.request.version={self.request.version}</h2>")
  10. self.write(f"<h2>self.request.headers={self.request.headers}</h2>")
  11. self.write(f"<h2>self.request.body={self.request.body}</h2>")
  12. self.write(f"<h2>self.request.remote_ip={self.request.remote_ip}</h2>")

输入localhost:7777/satori,得到页面如下

tornado.httputil.HTTPFile对象

  1. 接收到的是一个文件对象,属性有namebodycontent_type
  2. filename: 文件名
  3. body: 文件的数据实体
  4. content_type: 文件类型
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>古明地觉</title>
  6. </head>
  7. <body>
  8. <!--如果想上传文件,那么必须要加上enctype="multipart/form-data"-->
  9. <form action="/satori" method="post" enctype="multipart/form-data">
  10. <input type="file" name="picture">
  11. <input type="file" name="picture">
  12. <input type="file" name="txt">
  13. <input type="submit" value="提交">
  14. </form>
  15. </body>
  16. </html>
  1. import tornado.web
  2. import os
  3. class SatoriHandler(tornado.web.RequestHandler):
  4. def get(self):
  5. self.render("satori.html")
  6. def post(self, *args, **kwargs):
  7. BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
  8. file_dict = self.request.files
  9. '''
  10. 关于这里的file_dict,要详细的说一下
  11. 首先我们在html文件中,写了如下代码
  12. <input type="file" name="picture">
  13. <input type="file" name="picture">
  14. <input type="file" name="txt">
  15. 那么在文件上传提交之后,我们获取file_dict便是一个字典
  16. file_dict = {
  17. "picture": [{"filename": "xxx", "body": "xxx", "content_type": "xxx"},
  18. {"filename": "xxx", "body": "xxx", "content_type": "xxx"}],
  19. "txt": [{"filename": "xxx", "body": "xxx", "content_type": "xxx"}]
  20. }
  21. 我们在html中定义了name="picture"和name="txt"两个上传文件的input,那么"picture"和"txt"就是这个file_dict的两个key
  22. 每个key,分别对应一个列表。每个列表中存储的字典,便包含了上传文件的信息。因为可能上传多个文件,所以有多个字典。
  23. 比如我们这里的picture,列表里面就有两个字典,因为我们以name="picture"上传两个文件。
  24. 如果只有一个文件,那么key对应的value仍是一个列表,只不过这个列表里面只有一个字典,比如我们这里的txt
  25. example:我们上传了,satori.jpg(name="picture")、koishi.jpg(name="picture")、mmp.txt(name="txt")
  26. 那么file_dict如下:
  27. file_dict = {
  28. "picture": [{"filename": "satori.jpg", "body": b"二进制文件内容", "content_type": "img/jpeg"},
  29. {"filename": "koishi.jpg", "body": b"二进制文件内容", "content_type": "img/jpeg"}],
  30. "txt": [{"filename": "mmp.txt", "body": b"二进制文本内容", "content_type": "text/plain"}]
  31. }
  32. '''
  33. # 接下来便以上面的example进行上传
  34. '''
  35. name依次循环--->"picture","txt"
  36. '''
  37. for name in file_dict:
  38. '''
  39. file_arr依次循环--->[{"filename": "satori.jpg", "body": b"二进制文件内容", "content_type": "img/jpeg"},
  40. {"filename": "koishi.jpg", "body": b"二进制文件内容", "content_type": "img/jpeg"}],
  41. [{"filename": "mmp.txt", "body": b"二进制文本内容", "content_type": "text/plain"}]
  42. '''
  43. file_arr = file_dict[name]
  44. '''
  45. file_obj依次循环--->"{filename": "satori.jpg", "body": b"二进制文件内容", "content_type": "img/jpeg"},
  46. {"filename": "koishi.jpg", "body": b"二进制文件内容", "content_type": "img/jpeg"},
  47. {"filename": "mmp.txt", "body": b"二进制文本内容", "content_type": "text/plain"}
  48. '''
  49. for file_obj in file_arr:
  50. # filename:文件名
  51. filename = file_obj["filename"]
  52. # body:文件内容
  53. body = file_obj["body"]
  54. # 文件类型
  55. content_type = file_obj["content_type"]
  56. # 创建了一个upload_files目录,专门用来存放上传的文件
  57. with open(os.path.join(BASE_DIR, "upload_files", filename), "wb") as f:
  58. f.write(body)
  59. self.write(f"{filename}上传成功,文件类型为{content_type}<br>")

点击提交

再来看看upload_files目录,有没有上传的文件

显然上传是成功了的,以上操作便可以完成文件的上传

响应输出

1.self.write

  1. 原型:self.write(chunk)
  2. 作用:将数据写到缓冲区
  1. import tornado.web
  2. import json
  3. class SatoriHandler(tornado.web.RequestHandler):
  4. def get(self):
  5. self.write("我是self.write")
  6. self.write("我的作用是将数据写到缓冲区")
  7. # self.write还可以写入json文件
  8. dic = {"name": "古明地觉", "from": "东方地灵殿"}
  9. # 可以手动转化为json文件,那么Content-Type属性值为text/html
  10. self.write(json.dumps(dic))
  11. # 也可以直接利用write方法写入字典,那么Content-Type属性值为application/json
  12. self.write(dic)
  13. # self.finish(),表示手动关闭当次请求通道
  14. # 在self.finish()下面就不要在self.write了,否则报错
  15. self.finish()

2.self.set_header(name, value)

  1. 作用:手动设置一个名为name,值为value的响应头字段
  2. 参数:name,字段名称,value,字段值
  1. import tornado.web
  2. class SatoriHandler(tornado.web.RequestHandler):
  3. def get(self):
  4. self.set_header("satori", "koishi")
  5. self.write("我设置了一个响应头字段,可以检查元素看看")

3. set_default_header()

  1. 作用:在执行http方法之前被调用,可重写该方法预先设置默认的headers
  1. import tornado.web
  2. class SatoriHandler(tornado.web.RequestHandler):
  3. def set_default_headers(self):
  4. self.set_header("zgg", 666)
  5. self.set_header("mmp", 250)
  6. def get(self):
  7. self.set_header("satori", "koishi")
  8. self.set_header("love", "satori")
  9. self.write("我在两个地方设置了响应头字段")

4. self.set_status(status_code, reason=None)

  1. 作用:为相应设置状态码
  2. 参数:status_code,状态码值,为int,如果reason=None,那么状态码必须合法。
  3.    reason,描述状态码的词组,为string
  1. import tornado.web
  2. class SatoriHandler(tornado.web.RequestHandler):
  3. def get(self):
  4. self.set_header("satori", "koishi")
  5. self.set_header("love", "satori")
  6. # 404是合法的状态码,所以可以不指定reason
  7. self.set_status(status_code=404)
  8. self.write("我设置了状态码,去看看")

  1. import tornado.web
  2. class SatoriHandler(tornado.web.RequestHandler):
  3. def get(self):
  4. self.set_header("satori", "koishi")
  5. self.set_header("love", "satori")
  6. # 404是合法的状态码,指定一下reason
  7. self.set_status(status_code=404, reason="success")
  8. self.write("我设置了404,但是reason是success,去看看")

  1. import tornado.web
  2. class SatoriHandler(tornado.web.RequestHandler):
  3. def get(self):
  4. self.set_header("satori", "koishi")
  5. self.set_header("love", "satori")
  6. # 指定一个不存在的状态码,这时候要指定reason,否者状态码后面的描述是Unknow
  7. # 因为我们在指定404的时候,这些合法的状态码都是有意义的
  8. # 如404代表页面未找到,200代表成功,所以即使我们不指定reason,也会自动帮你添加
  9. # 但是如果指定一个不存在的状态码,那么最好指定reason
  10. self.set_status(status_code=666, reason="you 666")
  11. self.write("我设置了一个不合法的状态码,去看看")

5. self.redirect(url)

  1. 作用:重定向到某个url
  1. import tornado.web
  2. class SatoriHandler(tornado.web.RequestHandler):
  3. def get(self):
  4. self.redirect("http://www.baidu.com")

输入网址回车,会自动跳转到百度

6. self.send_error(status_code=500, **kwargs)

  1. 作用:抛出http错误状态码,默认为500,抛出错误后,tornado会自动调用write_error进行处理,并返回给页面
  2. 注意:在self.send_error之后就不要再响应输出了

7. self.write_error(status_code=500, **kwargs)

  1. 作用:用来处理self.send_error抛出的异常,并返回给浏览器错误界面
  1. import tornado.web
  2. class SatoriHandler(tornado.web.RequestHandler):
  3. def write_error(self, status_code, **kwargs):
  4. # self.send_error传入的状态码,会自动传入write_error当中
  5. # self.write_error和self.send_error中的status_code是相同的
  6. if status_code == 404:
  7. self.set_status(404, "damn it!!!")
  8. self.write("你妹的,活该资源找不到")
  9. def get(self):
  10. DoesSatoriLoveMe = self.get_argument("DoesSatoriLoveMe")
  11. if DoesSatoriLoveMe in ["yes", "YES", "Yes"]:
  12. self.write("哼。。给你个正常页面吧")
  13. else:
  14. self.send_error(404)

tornado请求与响应就先到这,下一节将介绍tornado的接口调用顺序与模板

2.(基础)tornado的请求与响应的更多相关文章

  1. tornado 03 请求与响应

    tornado 03 请求与响应 一.请求与响应 浏览器与服务器之间沟通的到底是什么信息 #服务器在后台一直保持运行着 #浏览器通过URL(路由.地址)发送请求 #服务器接收请求了通过tornado处 ...

  2. tornado的请求与响应

    tornado请求与响应相关 一.配置文件config.py 中的settings 有哪些配置: debug:设置tornado是否工作再调试模式下,默认为false 即工作再生产模式下 true的特 ...

  3. JavaWeb基础-Jsp的请求与响应

    JSP请求和相应 HTTP头信息 当浏览器请求一个网页时,它会向网络服务器发送一系列不能被直接读取的信息,因为这些信息是作为HTTP信息头的一部分来传送的. HttpServletRequest类 r ...

  4. 2.tornado请求与响应

    之前我们介绍了tornado的基础流程,但还遗留了一些问题.今天我们就来解决遗留问题并学习新的内容 settings,使用tornado.web.Application(handler, **sett ...

  5. tornado请求与响应

    tornado中处理请求与响应的类如下, 所有视图类必须继承该类: tornado.web.RequestHandler 一. 响应之self.write()方法 1.  该方法可返回值的类型: 当返 ...

  6. Spring Boot 2.x基础教程:如何扩展XML格式的请求和响应

    在之前的所有Spring Boot教程中,我们都只提到和用到了针对HTML和JSON格式的请求与响应处理.那么对于XML格式的请求要如何快速的在Controller中包装成对象,以及如何以XML的格式 ...

  7. struts2基础——请求与响应、获取web资源

    一.请求与响应 Action1.含义:(1) struts.xml 中的 action 元素,也指 from 表单的 action 属性,总之代表一个 struts2 请求.(2) 用于处理 Stru ...

  8. spring基础---->请求与响应的参数(一)

    这里面我们主要介绍一下spring中关于请求和响应参数数据的问题.爱,从来就是一件千回百转的事.不曾被离弃,不曾受伤害,怎懂得爱人?爱,原来是一种经历. spring中的请求与响应 一.spring中 ...

  9. http协议基础(二)请求和响应报文的构成

    http协议用于客户端和服务器之间的通信,请求访问资源的一方称为客户端,而提供资源响应的一方称为服务器端. 下面就是客户端和服务端之间简单的通信过程 PS:请求必须从客户端建立通信,服务端没收到请求之 ...

随机推荐

  1. 数据解析框架之Gson

    GSON是由Google提供的,用于JAVA对象与JSON字符串之间互相转换的一个解决方案.用处很多,比如在前后台通讯中,前台先将java对象转化成JSON,然后将JSON传输给后台交由后台处理——相 ...

  2. Dropdown 下拉菜单

    将动作或菜单折叠到下拉菜单中. 基础用法 移动到下拉菜单上,展开更多操作. 通过组件slot来设置下拉触发的元素以及需要通过具名slot为dropdown 来设置下拉菜单.默认情况下,下拉按钮只要ho ...

  3. 深度学习之NLP维基百科数据模型

    知识点 """ 1) from gensim.model import Word2Vec import jieba 2) opencc :将繁体字转换为简体字 转换命令: ...

  4. numpy之填充为nan的数据为该列平均值

    # coding=utf-8 import numpy as np ''' 填充nan的数据,为该列的平均值 ''' def fill_ndarray(t1): for i in range(t1.s ...

  5. 性能测试之JMeter远程模式

    性能测试之JMeter远程模式 事实上,你的JMeter客户端机器是不能表现出完美的压力请求,来模拟足够多的用户或由于网络限制去向服务施加压力,一种解决方法是通过一个JMeter去控制多个/远程JMe ...

  6. MySQL 对 IP 字段的排序问题

    MySQL 对 IP 字段的排序问题 问题描述 想对一张带有 IP 字段的表,对 IP 字段进行升序排序,方便查看每个段的 IP 信息. 表结构和表数据如下: SET NAMES utf8mb4; ; ...

  7. Python学习之初识

    第一章 1.1 typora 的安装与使用 1.1.1 标题的创建: 方法一:用 ###+空格 表示标题,几个#就是几级标题 方法二:菜单栏-->段落-->选择标题 1.1.2 有序列表与 ...

  8. flask 之(二) --- 视图|模版|模型

    Flask框架 打开pycharm编译器,新建一个Flask项目,选择提前建好的虚拟环境 . 项目结构: static:静态资源文件,可以直接被浏览器访问 templates:模版文件,必须在项目的p ...

  9. mysql账户授权

    mysql新加用户及授权 --登录数据库mysql -uroot -p --查询当前用户1.SELECT User, Host FROM mysql.user;2.select host,user,a ...

  10. vim编辑器详解(week1_day3)

    vi编辑器   作用:编辑文本文件中的内容的工具   命令历史   末行模式中,以:和/开头的命令都有历史纪录,可以首先键入:或/然后按上下箭头来选择某个历史命令.   启动vim   在命令行窗口中 ...