教你分分钟开发一个属于自己的python模块(一)——能够直接在浏览器打印的方法
曾经,用惯了python print命令的人,惊叹于python语法的精简;后来,用过了tornado、django等web开发框架,不得不佩服当初开发这些框架的人们。于是,我们开始使用它们的框架==》一个被重复了无数次的配置。那么问题来了,如果我很多次的完成某个领域的类似问题,我需要每次都去重复的配置吗?偶然间,我在想,能否在它们的框架上继续精简,以在某种用途上实现更加高效的开发。web框架的使用,包含server端和browser端。本次改装采用tornado框架。
首先,我们从接触python第一天的print(“Helloworld!”)开始。
干货开始:
首先我们来看一段精简的tornado代码:
import tornado.ioloop
import tornado.web class MainHandler(tornado.web.RequestHandler):
def get(self):
self.write("Hello, world") application = tornado.web.Application([
(r"/index", MainHandler),
]) if __name__ == "__main__":
application.listen(8888)
tornado.ioloop.IOLoop.instance().start()
上述代码实现了在浏览器端输出hello,world!从上到下各部分的功能依次是:模块导入、业务处理类、路由映射、服务端开启。
本博文详细介绍模块的改装,更多tornado基础内容,详见下面链接:
上述代码虽然实现了在浏览器的输出内容,但是有很多不足之处:
- 每次打印一个东西,用户都需要写那么多代码
- 只能支持字符串打印,不能支持字典、列表、元组等常见数据结构
我们知道,python的print用法很简单,只需要我们将需要打印的东西放在print内部,即可用一句话打印出我们想要的结果来。那么问题来了,有没有一种简单的方法能够类似print使用一句话在浏览器上打印出我们想要的任何数据结构?
答案当然是:有。没错,你没有看错,接下来,博主来带你一步一步实现这个神奇的功能。
模块导入:
import tornado.ioloop
import tornado.web
import json
和之前有所不同的是,我们增加了json模块,聪明你你应该已经猜到了,博主是想通过json实现对不同数据结构的支持,是的啊,没错!有人说,这不算什么,我也会,好,别走,继续往下看!更多精彩,详见下文!
解决思路:
事实上,解决这个问题,其实很简单,核心问题就是如何通过传参方式,将用户需要打印的数据传递给self.write。
要解决这个问题,我们需要指定,tornado框架哪些地方可以进行传参,我们再来看一下tornado代码:
import tornado.ioloop
import tornado.web class MainHandler(tornado.web.RequestHandler):
def get(self):
self.write("Hello, world") application = tornado.web.Application([
(r"/index", MainHandler),
]) if __name__ == "__main__":
application.listen(8888)
tornado.ioloop.IOLoop.instance().start()
我们采用由内向外的分析方法:
- 首先是self.write("Hello, world"),我们希望实现的结果是self.write(arg),arg代表用户传入的参数。而这个arg又要从哪里传入呢?包着它的是get方法,我们知道http协议的get方法可以通过在浏览器的url上通过问号加键值对的方式传入数据,可是难道用户每次打印数据都去浏览器的url输入吗?这明显不合理。因此get方法传参是行不通的。
- 接下来往外是业务处理类MainHandler,它能传参吗?我们知道类是可以通过init方法进行传参的,每次对类进行实例化的时候进行传参即可,我们需要自己定义个init方法并继承父类的init方法吗?可是问题是,这个MainHandler到底是在哪里进行实例化的,我们又需要在哪里对其进行传参呢?这里就到了tornado的源码部分,可是源码岂能随便去改,因此init方法传参也不合理。
- 为了遵循对源码封闭,对扩展开放的原则,其实tornado源码中已经为我们预留了位置,这就是传说中的initialize方法,也就是人们所说的“钩子”。
initialize方法如何使用呢?
首先需要自己定义一个类,用于复写源码中的initialize方法,因为源码中initialize方法其实什么事也没干。
class BaseHandler(tornado.web.RequestHandler):
def initialize(self,arg):
self.arg=arg
在这里,我们为initialize方法传入了参数arg,并给类增加属性self.arg=arg,这样做的目的是为了继承它的子类能够使用这个参数,这就是面向对象的封装,参数传递一次,这个类的子类的所有方法都是可以使用的。没错,聪明的你又发现了,等会如果我们的MainHandler类只要继承了BaseHandler类,那么MainHandler类的get方法中,就可以使用参数self.arg。下面就是MainHandler类的改装。
class MainHandler(BaseHandler):
def get(self):
self.write(self.arg)
做到这里,你可能已经发现:好吧,initialize方法传参我会了,可是用户输入的参数又是如何传入initialize方法呢?
我们发现唯一跟MainHandler类有关的,就是路由映射了,它是一个元组,元组第0个元素是正则匹配,第一个元素是业务处理类的类名,于是博主就想,这里能否接收第三个参数呢?能否进行传参呢?来看一眼路由映射:
application = tornado.web.Application([
(r"/index", MainHandler, ),
])
经过博主对Application类源码进行分析,果然,它是支持传第三个参数的:
源码截图:

源码中spec即每一个元组。更多源码问题,欢迎读者在下方评论,与博主进行探讨。经过博主多方咨询探讨,最终得出结论,第三个参数支持字典格式进行传递(源码中是**kwargs)。
路由映射改装代码:
application = tornado.web.Application([
(r"/index", MainHandler, dict(arg=json.dumps(request))),
])
同时,为了支持常见数据结构,博主采用json进行序列化数据。
以上就是整个改装流程,下面附整体代码模块和该模块的使用方法。
import tornado.ioloop
import tornado.web
import json class BaseHandler(tornado.web.RequestHandler):
def initialize(self,arg):
self.arg=arg class MainHandler(BaseHandler):
def get(self):
self.write(self.arg)
def print_to_browser(request,port=8888):
application = tornado.web.Application([
(r"/", MainHandler, dict(arg=json.dumps(request))),
])
application.listen(port)
tornado.ioloop.IOLoop.instance().start()
上述模块是博主原创,封装了tornado路由映射、服务端开启,支持传参,第一个参数即需要打印的内容,第二个参数为可选参数,默认端口8888,如果用户有传递,则以用户输入的参数为准。
鉴于博主有文章被多家网站盗用,鉴于此,原谅博主在此插播声明一条:本博文为博主原创,转账请注明原文链接:http://www.cnblogs.com/wanghzh/p/5869336.html,谢谢合作!
模块使用:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from my.mytornado import print_to_browser #导入上述模块 print_to_browser([1,2,3,4,])
结果示例截图:

上述使用方法是不是同python自带的print一样简单呢,支持字符串、字典、列表、元组等数据结构。默认域名:127.0.0.1,默认端口:8888。用户只需开启浏览器客户端即可(127.0.0.1:8888)。
如果您觉得本文对您有参考价值,,欢迎帮博主点下文章下方的推荐,非常谢谢!
教你分分钟开发一个属于自己的python模块(一)——能够直接在浏览器打印的方法的更多相关文章
- 教你如何开发一个完败Miracast的投屏新功能
手机与电视,是陪伴在我们生活最常见,陪伴最长久的智能设备.迅猛发展的移动终端与通信技术,赋予了手机更广阔多元的应用生态,大屏电视则以大视野和震撼影音,弥补了手里方寸带来的视觉局限.而今,手机的延伸 ...
- 如何开发一个基于 Docker 的 Python 应用
前言 Python 家族成员繁多,解决五花八门的业务需求.这里将通过 Python 明星项目 IPython Notebook,使其容器化,让大家掌握基础的 Docker 使用方法. IPython ...
- Python开发【第一篇】Python模块中特殊变量
模块中特殊变量 生产环境中,常用的就是__name__和__file__ __doc__ __package__ __cached__ __name__ __file__ 一. __doc__ #获 ...
- Android | 教你如何用代码开发一个拍照翻译小程序
引子 想必有很多小伙伴喜欢外出旅游,能去海外玩一圈那是更好不过了,旅游前大家一定会对吃.穿.住.行.游玩路线做各种攻略,然后满怀期待的出发- 想象中的旅游 出发前,想象中的旅游目的地可能有漂亮 ...
- 如何用HMS Nearby Service给自己的APP开发一个名片交换功能?
在工作和生活中,遇见新的同事或者合作伙伴,交换名片是一个常见的用户需求,纸质名片常忘带.易丢失,是客户的一个痛点.因此,市场上出现了很多交换电子名片的APP和小程序.那么,如何给自己的APP开发一 ...
- 【Nginx】开发一个HTTP过滤模块
与HTTP处理模块不同.HTTP过滤模块的工作是对发送给用户的HTTP响应做一些加工. server返回的一个响应能够被随意多个HTTP过滤模块以流水线的方式依次处理.HTTP响应分为头部和包体,ng ...
- 手把手教你用Vue2+webpack+node开发一个H5 app
手把手教你用Vue2+webpack+node开发一个H5 app 前一篇vue2 + webpack + node 开发一个小demo说到了用vue的一些基本用法,这一篇就讲一个复杂一点的更完整的 ...
- 手把手教你使用FineUI开发一个b/s结构的取送货管理信息系统系列博文索引
近阶段接到一些b/s类型的软件项目,但是团队成员之前大部分没有这方面的开发经验,于是自己选择了一套目前网上比较容易上手的开发框架(FineUI),计划录制一套视频讲座,来讲解如何利用FineUI快速开 ...
- Android | 教你如何用华为HMS MLKit 图像分割 SDK开发一个证件照DIY小程序
Android | 教你如何用华为HMS MLKit 图像分割 SDK开发一个证件照DIY小程序 引子 上期给大家介绍了如何使用如何用华为HMS MLKit SDK 三十分钟在安卓上开发一个微笑抓 ...
随机推荐
- GRE与Vxlan网络详解
1. GRE 1.1 概念 GRE全称是Generic Routing Encapsulation,是一种协议封装的格式,具体格式内容见:https://tools.ietf.org/html/rfc ...
- 【Codeforces717F】Heroes of Making Magic III 线段树 + 找规律
F. Heroes of Making Magic III time limit per test:3 seconds memory limit per test:256 megabytes inpu ...
- Linux下C高手成长过程
建议学习路径: 首先先学学编辑器,vim, emacs什么的都行. 然后学make file文件,只要知道一点就行,这样就可以准备编程序了. 然后看看<C程序设计语言>K&R, ...
- 个人学习记录2:ajax跨域封装
/** * 跨域提交公用方法 * @param param 参数 * @param url 跨域的地址 * @param callFun 回调函数 callFun(data) */ function ...
- 优化Table View
优化Table View Table view需要有很好的滚动性能,不然用户会在滚动过程中发现动画的瑕疵. 为了保证table view平滑滚动,确保你采取了以下的措施: 正确使用`reuseIden ...
- java 部分注解说明(待补充)
内容 所代表的意思 @RequestMapping(params = "save") @ResponseBody 将内容或对象作为http响应正文返回,并调用适合HttpMessa ...
- 11月1日上午PHP------empty、 is_null、isset、unset的区别
1.empty 判断一个变量是否为"空".null.false.00.0.'0′.』.为以上值的变量在检测時都将返回true. 2.isset 判断一个变量是否已经设置.0.00. ...
- %我的 tex 模版
%我的 tex 模版 \documentclass[UTF8,a1paper,landscape]{ctexart}%UTF8 中文支持,a1paper 纸张大小,landscape 横向版面,cte ...
- yield和send的执行循序彻底搞清
yield: 对于yield方法和Generator的send同时使用时的执行顺序一直搞不清,今天看到这篇 理解PHP中的Generator 加上测试,终于搞清了. 总结一下上文中的结论: Gener ...
- 关于学习angularJS 的 心里路程(二)
这一次主要的学习内容是 ng-route(本次的项目由于种种原因吧,我们采用了ui-router,而不是原生的ng-route) * 配置路由. * 注意这里采用的是ui-router这个路由,而不是 ...