教你分分鐘開發一個屬於自己的python模塊(一)——能夠直接在瀏覽器打印的方法

分類:IT技術 時間:2016-10-17

  曾經,用慣了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基礎內容,詳見下面鏈接:

  • tornado高效開發必備之源碼詳解
  • tornado web高級開發項目之抽屜官網的頁面登陸驗證、form驗證、點贊、評論、文章分頁處理、發送郵箱驗證碼、登陸驗證碼、註冊、發布文章、上傳圖片

  • Web框架之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)。

如果您覺得本文對您有參考價值,,歡迎幫博主點下文章下方的推薦,非常謝謝!

 


Tags: 驗證碼 瀏覽器 開發項目 browser python

文章來源:


ads
ads

相關文章
ads

相關文章

ad