一硅卢、給路由添加正則表達(dá)式
-
給路由參數(shù)添加正則表達(dá)式的原因:在實(shí)際開(kāi)發(fā)時(shí)霜大,url中往往會(huì)帶有很多的參數(shù),例如:
/add/0003.htm
l 中0003
就是參數(shù)底燎,如果沒(méi)有正則的話(huà)鳖粟,那么就需要編寫(xiě)N
次@route
來(lái)進(jìn)行添加url
對(duì)應(yīng)的函數(shù)到字典中社裆,此時(shí)字典中的鍵值對(duì)有N
個(gè),浪費(fèi)空間向图,而采用了正則的話(huà),那么只要編寫(xiě)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ù)的裝飾器來(lái)做路由 :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='用戶(hù)名', password='密碼', charset='utf8') # 獲得Cursor對(duì)象 cursor = conn.cursor() sql = """select * from info where code=%s;""" cursor.execute(sql,(stock_code,)) print("************-----------1------------------") # 如果要是沒(méi)有這個(gè)股票代碼嗜傅,那么就認(rèn)為是非法的請(qǐng)求 if not cursor.fetchone(): cursor.close() conn.close() return "沒(méi)有這支股票,大哥 檩赢,我們是創(chuàng)業(yè)公司吕嘀,請(qǐng)手下留情..." print("************-----------2------------------") # 3.在股票存在的情況下查看股票是否關(guān)注過(guò) 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,)) # 如果查出來(lái)表示關(guān)注過(guò) if cursor.fetchone(): cursor.close() conn.close() return "已經(jīng)關(guān)注過(guò)了,請(qǐng)勿重復(fù)關(guān)注..." print("************-----------3------------------") # 4.在沒(méi)有關(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)沒(méi)有對(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
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)容的時(shí)候會(huì)對(duì)內(nèi)容進(jìn)行編碼,如果我們的框架在接收到消息后不進(jìn)行解碼直接寫(xiě)入數(shù)據(jù)庫(kù)碟摆,我們服務(wù)器里面存的是url編碼的內(nèi)容晃财,所以我們需要對(duì)內(nèi)容進(jìn)行解碼,再存到數(shù)據(jù)庫(kù)典蜕,這樣下次讀取出來(lái)的時(shí)候不再是url編碼的內(nèi)容
三断盛、logging日志模塊
3.1、開(kāi)發(fā)過(guò)程中出現(xiàn)bug是必不可免的愉舔,你會(huì)怎樣debug钢猛?從第1行代碼開(kāi)始看么?還是有個(gè)文件里面記錄著哪里錯(cuò)了更方便呢P汀C酢!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)重的;
解釋?zhuān)?/p>
-
DEBUG
:詳細(xì)的信息,通常只出現(xiàn)在診斷問(wèn)題上 -
INFO
:確認(rèn)一切按預(yù)期運(yùn)行 -
WARNING
:一個(gè)跡象表明,一些意想不到的事情發(fā)生了,或表明一些問(wèn)題在不久的將來(lái)(例如征椒。磁盤(pán)空間低”)。這個(gè)軟件還能按預(yù)期工作湃累。 -
ERROR
:更嚴(yán)重的問(wèn)題,軟件沒(méi)能執(zhí)行一些功能 -
CRITICAL
:一個(gè)嚴(yán)重的錯(cuò)誤,這表明程序本身可能無(wú)法繼續(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') # 開(kāi)始使用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:要寫(xiě)入的日志文件名字 filemode:日志寫(xiě)入的模式宁玫,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') # 開(kāi)始使用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), 還要寫(xiě)入日志文件
這就需要一個(gè)叫作Logger
的對(duì)象來(lái)幫忙罚屋,下面將對(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í)總開(kāi)關(guān) # 第二步撕彤,創(chuàng)建一個(gè)handler,用于寫(xiě)入日志文件 logfile = './log.txt' fh = logging.FileHandler(logfile, mode='a') # open的打開(kāi)模式這里可以進(jìn)行參考 fh.setLevel(logging.INFO) # 輸出到file的log等級(jí)的開(kāi)關(guān) # 第三步猛拴,再創(chuàng)建一個(gè)handler羹铅,用于輸出到控制臺(tái) ch = logging.StreamHandler() ch.setLevel(logging.WARNING) # 輸出到console的log等級(jí)的開(kāi)關(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、日志格式說(shuō)明
-
logging.basicConfig
函數(shù)中跛溉,可以指定日志的輸出格式format焊切,這個(gè)參數(shù)可以輸出很多有用的信息,如下:%(levelno)s: 打印日志級(jí)別的數(shù)值 %(levelname)s: 打印日志級(jí)別名稱(chēng) %(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: 打印線(xiàn)程ID %(threadName)s: 打印線(xiàn)程名稱(chēng) %(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)容嚎尤。
-