Python mini-web框架5:路由添加正則和log日志功能

一、給路由添加正則表達(dá)式

  • 給路由參數(shù)添加正則表達(dá)式的原因:在實際開發(fā)時,url中往往會帶有很多的參數(shù),例如:/add/0003.html 中0003 就是參數(shù),如果沒有正則的話,那么就需要編寫 N@route 來進(jìn)行添加 url 對應(yīng)的函數(shù)到字典中,此時字典中的鍵值對有 N 個,浪費(fèi)空間,而采用了正則的話,那么只要編寫1@route 就可以完成多個 url 例如/add/0008.html/add/0003.html 等對同一個函數(shù),此時的字典中鍵值對減少很多,如下示例代碼

    import re
    from pymysql import connect
    
    # 定義一個空子典
    URL_FUNC_DICT = dict()
    
    
    def route(url):
            """
            帶參數(shù)的裝飾器來做路由
            :param url: 請求的url
            :return: 返回一個裝飾器
            """
            def set_func(func):
                # 往空子典里面添加元素
                URL_FUNC_DICT[url] = func
    
                def call_func(*args, **kwargs):
                         return func(*args, **kwargs)
    
                return call_func
    
            return set_func
    
    
    @route(r"/add/(\d+)\.html")
    def add_focus(ret):
    
           # 1.獲取股票代碼
           stock_code = ret.group(1)
    
           # 2.判斷下是否有這個股票代碼
           # 創(chuàng)建Connection連接
           conn = connect(host='域名或者公網(wǎng)IP', port=3306, database='數(shù)據(jù)庫名', user='用戶名', password='密碼',
                 charset='utf8')
           # 獲得Cursor對象
           cursor = conn.cursor()
           sql = """select * from info where code=%s;"""
           cursor.execute(sql,(stock_code,))
    
           print("************-----------1------------------")
    
           # 如果要是沒有這個股票代碼,那么就認(rèn)為是非法的請求
           if not cursor.fetchone():
                cursor.close()
                conn.close()
                return "沒有這支股票,大哥 ,我們是創(chuàng)業(yè)公司,請手下留情..."
    
           print("************-----------2------------------")
    
           # 3.在股票存在的情況下查看股票是否關(guān)注過
           sql = """select * from focus as f inner join info as i on f.info_id = i.id where i.code=%s;"""
           cursor.execute(sql,(stock_code,))
           # 如果查出來表示關(guān)注過
           if cursor.fetchone():
                 cursor.close()
                 conn.close()
                 return "已經(jīng)關(guān)注過了,請勿重復(fù)關(guān)注..."
    
           print("************-----------3------------------")
    
          # 4.在沒有關(guān)注的情況下,進(jìn)行關(guān)注,也就是往關(guān)注的信息表里面添加數(shù)據(jù)
          sql = """insert into focus (info_id) select id from info where code = %s;"""
          cursor.execute(sql,(stock_code,))
          conn.commit()
          cursor.close()
          conn.close()
    
          return "關(guān)注成功"
    
    
    def application(evn, start_reponse):
            start_reponse('200 OK', [('Content-Type', 'text/html;charset=utf-8')])
            file_name = evn['PATH_INFO']
            try:
                for url,func in URL_FUNC_DICT.items():
                       ret = re.match(url,file_name)
                       if ret:
                             return func(ret)
                       else:
                             return "請求的url(%s)沒有對應(yīng)的函數(shù)...." % file_name
    
            except Exception as ret:
                 return "產(chǎn)生了異常:%s"% str(ret)
    

二、url 編碼

  • 2.1、python3對url編解碼
    導(dǎo)入庫 urllib.parse

    import urllib.parse
    

    Python3 url編碼

    print(urllib.parse.quote("不忘初心,方得始終!"))
    打印結(jié)果:%E4%B8%8D%E5%BF%98%E5%88%9D%E5%BF%83%EF%BC%8C%E6%96%B9%E5%BE%97%E5%A7%8B%E7%BB%88%EF%BC%81
    

    Python3 url解碼

    print(urllib.parse.unquote('%E4%B8%8D%E5%BF%98%E5%88%9D%E5%BF%83%EF%BC%8C%E6%96%B9%E5%BE%97%E5%A7%8B%E7%BB%88%EF%BC%81'))
    打印結(jié)果是:不忘初心,方得始終!
    

    完整的代碼如下:

    import urllib.parse
    
    text = urllib.parse.quote("不忘初心,方得始終!")
    
    print("url編碼后的文字=%s"%text)
    
    text = urllib.parse.unquote(text)
    
    print("url解碼后的文字=%s"%text)
    
  • 2.2、瀏覽器往服務(wù)器傳內(nèi)容的時候會對內(nèi)容進(jìn)行編碼,如果我們的框架在接收到消息后不進(jìn)行解碼直接寫入數(shù)據(jù)庫,我們服務(wù)器里面存的是url編碼的內(nèi)容,所以我們需要對內(nèi)容進(jìn)行解碼,再存到數(shù)據(jù)庫,這樣下次讀取出來的時候不再是url編碼的內(nèi)容

三、logging日志模塊

  • 3.1、開發(fā)過程中出現(xiàn)bug是必不可免的,你會怎樣debug?從第1行代碼開始看么?還是有個文件里面記錄著哪里錯了更方便呢!!!log日志,Python中有個logging模塊可以完成相關(guān)信息的記錄,在debug時用它往往事半功倍

  • 3.2、日志級別:日志一共分成5個等級,從 低到高 分別是:

    DEBUG      # 調(diào)試模式
    INFO       # 確認(rèn)一切按預(yù)期運(yùn)行
    WARNING    # 警告
    ERROR      # 錯誤
    CRITICAL   # critical 英[?kr?t?kl]  嚴(yán)重的;
    

    解釋:

    • DEBUG:詳細(xì)的信息,通常只出現(xiàn)在診斷問題上
    • INFO:確認(rèn)一切按預(yù)期運(yùn)行
    • WARNING:一個跡象表明,一些意想不到的事情發(fā)生了,或表明一些問題在不久的將來(例如。磁盤空間低”)。這個軟件還能按預(yù)期工作。
    • ERROR:更嚴(yán)重的問題,軟件沒能執(zhí)行一些功能
    • CRITICAL:一個嚴(yán)重的錯誤,這表明程序本身可能無法繼續(xù)運(yùn)行
    • 總結(jié):這5個等級,也分別對應(yīng)5種打日志的方法: debug 、info 、warning 、error 、critical。默認(rèn)的是WARNING,當(dāng)在WARNING或之上時才被跟蹤。
  • 3.3、日志輸出
    有兩種方式記錄跟蹤,一種輸出控制臺,另一種是記錄到文件中,如日志文件。

    • (1)、將日志輸出到控制臺,比如,logTest.py 如下:

      import logging
      
      logging.basicConfig(level=logging.DEBUG,
                      format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s')
      # 開始使用log功能
      logging.debug('這是 loggging debug message')
      logging.info('這是 loggging info message')
      logging.warning('這是 loggging a warning message')
      logging.error("這是logging error message")
      logging.critical("這是logging critical message")
      

      打印結(jié)果如下:

      2019-01-17 10:00:53,331 - logTest.py[line:21] - DEBUG: 這是 loggging debug message
      2019-01-17 10:00:53,331 - logTest.py[line:22] - INFO: 這是 loggging info message
      2019-01-17 10:00:53,331 - logTest.py[line:23] - WARNING: 這是 loggging a warning message
      2019-01-17 10:00:53,331 - logTest.py[line:24] - ERROR: 這是logging error message
      2019-01-17 10:00:53,331 - logTest.py[line:25] - CRITICAL: 這是logging critical message
      
    • (2)、將日志輸出到文件log.txt,比如,logTest2.py 如下:

      import logging
      
      
      """
         level:日志等級,5個等級,從小到大依次是:debug、info、warning、error、critical
         filename:要寫入的日志文件名字
         filemode:日志寫入的模式,a是追加日志信息 w是刪除后添加新的日志信息
         format:格式,asctime 時間、filename 報錯文件名、lineno 行數(shù) 、levelname 報錯的等級、message 報錯的信息
      """
      logging.basicConfig(level=logging.DEBUG,
                 filename='./log.txt',
                 filemode='a',
                 format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s')
      
      # 開始使用log功能
      logging.debug('這是 loggging debug message')
      logging.info('這是 loggging info message')
      logging.warning('這是 loggging a warning message')
      logging.error("這是logging error message")
      logging.critical("這是logging critical message")
      

      運(yùn)行后會生成一個 log.txt 文件

      運(yùn)行后會生成一個 `log.txt` 文件

    • (3)、既要把日志輸出到控制臺, 還要寫入日志文件
      這就需要一個叫作 Logger 的對象來幫忙,下面將對他進(jìn)行詳細(xì)介紹,現(xiàn)在這里先學(xué)習(xí)怎么實現(xiàn)把日志既要輸出到控制臺又要輸出到文件的功能。

      import logging  
      
      # 第一步,創(chuàng)建一個logger  
      logger = logging.getLogger()  
      logger.setLevel(logging.DEBUG)  # Log等級總開關(guān)  
      
      # 第二步,創(chuàng)建一個handler,用于寫入日志文件  
      logfile = './log.txt'  
      fh = logging.FileHandler(logfile, mode='a')  # open的打開模式這里可以進(jìn)行參考
      fh.setLevel(logging.INFO)  # 輸出到file的log等級的開關(guān)  
      
      # 第三步,再創(chuàng)建一個handler,用于輸出到控制臺  
      ch = logging.StreamHandler()  
      ch.setLevel(logging.WARNING)   # 輸出到console的log等級的開關(guān)  
      
      # 第四步,定義handler的輸出格式  
      formatter = logging.Formatter("%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s")  
      fh.setFormatter(formatter)  
      ch.setFormatter(formatter)  
      
      # 第五步,將logger添加到handler里面  
      logger.addHandler(fh)  
      logger.addHandler(ch)  
      
      # 日志  
      logger.debug('這是 logger debug message')  
      logger.info('這是 logger info message')  
      logger.warning('這是 logger warning message')  
      logger.error('這是 logger error message')  
      logger.critical('這是 logger critical message')
      

      運(yùn)行時終端的輸出結(jié)果:

      2019-01-17 11:21:01,785 - logTest3.py[line:28] - WARNING: 這是 logger warning message
      2019-01-17 11:21:01,785 - logTest3.py[line:29] - ERROR: 這是 logger error message
      2019-01-17 11:21:01,785 - logTest3.py[line:30] - CRITICAL: 這是 logger critical message
      

      log.txt 中,有如下數(shù)據(jù):

      2019-01-17 11:21:01,784 - logTest3.py[line:27] - INFO: 這是 logger info message
      2019-01-17 11:21:01,785 - logTest3.py[line:28] - WARNING: 這是 logger warning message
      2019-01-17 11:21:01,785 - logTest3.py[line:29] - ERROR: 這是 logger error message
      2019-01-17 11:21:01,785 - logTest3.py[line:30] - CRITICAL: 這是 logger critical message
      
  • 3.4、日志格式說明

    • logging.basicConfig函數(shù)中,可以指定日志的輸出格式format,這個參數(shù)可以輸出很多有用的信息,如下:

      %(levelno)s: 打印日志級別的數(shù)值
      %(levelname)s: 打印日志級別名稱
      %(pathname)s: 打印當(dāng)前執(zhí)行程序的路徑,其實就是sys.argv[0]
      %(filename)s: 打印當(dāng)前執(zhí)行程序名
      %(funcName)s: 打印日志的當(dāng)前函數(shù)
      %(lineno)d: 打印日志的當(dāng)前行號
      %(asctime)s: 打印日志的時間
      %(thread)d: 打印線程ID
      %(threadName)s: 打印線程名稱
      %(process)d: 打印進(jìn)程ID
      %(message)s: 打印日志信息
      
    • 在工作中給的常用格式如下:

      format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s'
      

      這個格式可以輸出日志的打印時間,是哪個模塊輸出的,輸出的日志級別是什么,以及輸入的日志內(nèi)容。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,702評論 6 534
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,615評論 3 419
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,606評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,044評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 71,826評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,227評論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,307評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,447評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,992評論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,807評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,001評論 1 370
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,550評論 5 361
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,243評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,667評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,930評論 1 287
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,709評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 47,996評論 2 374

推薦閱讀更多精彩內(nèi)容

  • From:Python之日志處理(logging模塊) - 云游道士 - 博客園 https://www.cnbl...
    vigny的先生閱讀 2,701評論 3 5
  • 前言 在自動化測試實踐過程中,必不可少的就是進(jìn)行日志管理,方便調(diào)試和生產(chǎn)問題追蹤,python提供了logg...
    苦葉子閱讀 837評論 0 0
  • 常用模塊 認(rèn)識模塊 什么是模塊 什么是模塊? 常見的場景:一個模塊就是一個包含了python定義和聲明的文件,文...
    go以恒閱讀 1,980評論 0 6
  • 這是標(biāo)題 這是標(biāo)題 這是標(biāo)題 這是標(biāo)題 這是標(biāo)題 -列表第一項-列表第二項1.有序列表第一項2.有序列表第二項百度...
    Dizoo閱讀 323評論 0 0
  • 喜歡配色,窗簾色調(diào)也很和諧。但是1:穿衣鏡的地方更喜歡搭成一個簡易迷你隔斷區(qū)出來2:入戶空間實用性不好, 客餐廳全...
    TheraZhao閱讀 486評論 2 8