一、給路由添加正則表達(dá)式
-
給路由參數(shù)添加正則表達(dá)式的原因:在實際開發(fā)時,url中往往會帶有很多的參數(shù),例如:
/add/0003.htm
l 中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)容。
-