一倘潜、給路由添加正則表達(dá)式
給路由參數(shù)添加正則表達(dá)式的原因:在實(shí)際開發(fā)時(shí)佃迄,url中往往會(huì)帶有很多的參數(shù)茶行,例如:/add/0003.html 中0003 就是參數(shù)沃呢,如果沒有正則的話断序,那么就需要編寫 N 次 @route 來進(jìn)行添加 url 對(duì)應(yīng)的函數(shù)到字典中流纹,此時(shí)字典中的鍵值對(duì)有 N 個(gè),浪費(fèi)空間违诗,而采用了正則的話,那么只要編寫1次 @route 就可以完成多個(gè) url 例如/add/0008.html漱凝、/add/0003.html 等對(duì)同一個(gè)函數(shù),此時(shí)的字典中鍵值對(duì)減少很多较雕,如下示例代碼
import re
from pymysql import connect
# 定義一個(gè)空子典
URL_FUNC_DICT = dict()
def route(url):
? ? ? ? """
? ? ? ? 帶參數(shù)的裝飾器來做路由
? ? ? ? :param url: 請(qǐng)求的url
? ? ? ? :return: 返回一個(gè)裝飾器
? ? ? ? """
? ? ? ? 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.判斷下是否有這個(gè)股票代碼
? ? ? # 創(chuàng)建Connection連接
? ? ? conn = connect(host='域名或者公網(wǎng)IP', port=3306, database='數(shù)據(jù)庫(kù)名', user='用戶名', password='密碼',
? ? ? ? ? ? charset='utf8')
? ? ? # 獲得Cursor對(duì)象
? ? ? cursor = conn.cursor()
? ? ? sql = """select * from info where code=%s;"""
? ? ? cursor.execute(sql,(stock_code,))
? ? ? print("************-----------1------------------")
? ? ? # 如果要是沒有這個(gè)股票代碼碉哑,那么就認(rèn)為是非法的請(qǐng)求
? ? ? if not cursor.fetchone():
? ? ? ? ? ? cursor.close()
? ? ? ? ? ? conn.close()
? ? ? ? ? ? return "沒有這支股票,大哥 亮蒋,我們是創(chuàng)業(yè)公司扣典,請(qǐng)手下留情..."
? ? ? 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)注過了,請(qǐng)勿重復(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 "請(qǐng)求的url(%s)沒有對(duì)應(yīng)的函數(shù)...." % file_name
? ? ? ? except Exception as ret:
? ? ? ? ? ? return "產(chǎn)生了異常:%s"% str(ret)
二、url 編碼
2.1趁怔、python3對(duì)url編解碼
導(dǎo)入庫(kù) urllib.parse
importurllib.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)容的時(shí)候會(huì)對(duì)內(nèi)容進(jìn)行編碼,如果我們的框架在接收到消息后不進(jìn)行解碼直接寫入數(shù)據(jù)庫(kù)鳍侣,我們服務(wù)器里面存的是url編碼的內(nèi)容丁稀,所以我們需要對(duì)內(nèi)容進(jìn)行解碼,再存到數(shù)據(jù)庫(kù)倚聚,這樣下次讀取出來的時(shí)候不再是url編碼的內(nèi)容
三线衫、logging日志模塊
3.1、開發(fā)過程中出現(xiàn)bug是必不可免的惑折,你會(huì)怎樣debug授账?從第1行代碼開始看么枯跑?還是有個(gè)文件里面記錄著哪里錯(cuò)了更方便呢!0兹取全肮!log日志,Python中有個(gè)logging模塊可以完成相關(guān)信息的記錄棘捣,在debug時(shí)用它往往事半功倍
3.2辜腺、日志級(jí)別:日志一共分成5個(gè)等級(jí),從低到高分別是:
DEBUG # 調(diào)試模式
INFO? ? ? # 確認(rèn)一切按預(yù)期運(yùn)行
WARNING? ? # 警告
ERROR? ? ? # 錯(cuò)誤
CRITICAL? # critical 英[?kr?t?kl]? 嚴(yán)重的;
解釋:
DEBUG:詳細(xì)的信息,通常只出現(xiàn)在診斷問題上
INFO:確認(rèn)一切按預(yù)期運(yùn)行
WARNING:一個(gè)跡象表明,一些意想不到的事情發(fā)生了,或表明一些問題在不久的將來(例如乍恐。磁盤空間低”)评疗。這個(gè)軟件還能按預(yù)期工作。
ERROR:更嚴(yán)重的問題,軟件沒能執(zhí)行一些功能
CRITICAL:一個(gè)嚴(yán)重的錯(cuò)誤,這表明程序本身可能無法繼續(xù)運(yùn)行
總結(jié):這5個(gè)等級(jí)茵烈,也分別對(duì)應(yīng)5種打日志的方法: debug 百匆、info 、warning 呜投、error 加匈、critical。默認(rèn)的是WARNING仑荐,當(dāng)在WARNING或之上時(shí)才被跟蹤雕拼。
3.3、日志輸出
有兩種方式記錄跟蹤粘招,一種輸出控制臺(tái)啥寇,另一種是記錄到文件中,如日志文件洒扎。
(1)辑甜、將日志輸出到控制臺(tái),比如袍冷,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:日志等級(jí)邓线,5個(gè)等級(jí),從小到大依次是:debug乃戈、info褂痰、warning亩进、error症虑、critical
? filename:要寫入的日志文件名字
? filemode:日志寫入的模式,a是追加日志信息 w是刪除后添加新的日志信息
? format:格式归薛,asctime 時(shí)間谍憔、filename 報(bào)錯(cuò)文件名匪蝙、lineno 行數(shù) 、levelname 報(bào)錯(cuò)的等級(jí)习贫、message 報(bào)錯(cuò)的信息
"""
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)行后會(huì)生成一個(gè)?log.txt?文件
(3)逛球、既要把日志輸出到控制臺(tái), 還要寫入日志文件
這就需要一個(gè)叫作 Logger 的對(duì)象來幫忙苫昌,下面將對(duì)他進(jìn)行詳細(xì)介紹颤绕,現(xiàn)在這里先學(xué)習(xí)怎么實(shí)現(xiàn)把日志既要輸出到控制臺(tái)又要輸出到文件的功能。
import logging
# 第一步祟身,創(chuàng)建一個(gè)logger?
logger = logging.getLogger()?
logger.setLevel(logging.DEBUG)? # Log等級(jí)總開關(guān)?
# 第二步奥务,創(chuàng)建一個(gè)handler,用于寫入日志文件?
logfile = './log.txt'?
fh = logging.FileHandler(logfile, mode='a')? # open的打開模式這里可以進(jìn)行參考
fh.setLevel(logging.INFO)? # 輸出到file的log等級(jí)的開關(guān)?
# 第三步袜硫,再創(chuàng)建一個(gè)handler氯葬,用于輸出到控制臺(tái)?
ch = logging.StreamHandler()?
ch.setLevel(logging.WARNING)? # 輸出到console的log等級(jí)的開關(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)行時(shí)終端的輸出結(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闯睹,這個(gè)參數(shù)可以輸出很多有用的信息,如下:
%(levelno)s: 打印日志級(jí)別的數(shù)值
%(levelname)s: 打印日志級(jí)別名稱
%(pathname)s: 打印當(dāng)前執(zhí)行程序的路徑担神,其實(shí)就是sys.argv[0]
%(filename)s: 打印當(dāng)前執(zhí)行程序名
%(funcName)s: 打印日志的當(dāng)前函數(shù)
%(lineno)d: 打印日志的當(dāng)前行號(hào)
%(asctime)s: 打印日志的時(shí)間
%(thread)d: 打印線程ID
%(threadName)s: 打印線程名稱
%(process)d: 打印進(jìn)程ID
%(message)s: 打印日志信息
在工作中給的常用格式如下:
format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s'
這個(gè)格式可以輸出日志的打印時(shí)間瞻坝,是哪個(gè)模塊輸出的,輸出的日志級(jí)別是什么杏瞻,以及輸入的日志內(nèi)容所刀。
作者:IIronMan
鏈接:http://www.reibang.com/p/a35ef3af2800
來源:簡(jiǎn)書
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán)捞挥,非商業(yè)轉(zhuǎn)載請(qǐng)注明出處浮创。