您的位置:首页 > 编程语言 > Python开发

Python高级 -- 12 mini_frame框架添加路由、路由支持正则、Log日志功能

2018-03-24 14:55 756 查看

一、路由

1、mini_frame中实现简单的路由功能

mini_frame.py

# coding=UTF-8
import re

def index():
with open("./templates/index.html") as f:

content = f.read()

# 使用正则表达式替换源模版中的数据

from_mysql_data = "这里以后放的是从数据库中查询出来的数据"

content = re.sub(r"\{%content%\}", from_mysql_data, content)

return content

def center():
with open("./templates/center.html") as f:

return f.read()

URL_FUN_DIC = {
"/index.py":index,
"/center.py":center
}

def application(env, start_response):
start_response('200 OK', [('Content-Type','text/html;charset=utf-8')])

file_name = env['PATH_INFO']

"""
if file_name == "/index.py":
return index()
elif file_name == "/center.py":
return center()
else:
return "我爱你中国..."
"""
func = URL_FUN_DIC[file_name]
return func()

2、使用装饰器完成mini_frame.py的路由功能

mini_frame.py

# coding=UTF-8
import re

URL_FUN_DIC = dict()

def route(url):
def set_func(func):
# 在执行装饰的过程中将参数添加到字典中
URL_FUN_DIC[url] = func
def call_func(*args, **kwargs):
return func(*args, **kwargs)
return call_func
return set_func

@route("/index.py")
def index():
with open("./templates/index.html") as f:

content = f.read()

# 使用正则表达式替换源模版中的数据

from_mysql_data = "这里以后放的是从数据库中查询出来的数据"

content = re.sub(r"\{%content%\}", from_mysql_data, content)

return content

@route("/center.py")
def center():
with open("./templates/center.html") as f:

return f.read()

def application(env, start_response):
start_response('200 OK', [('Content-Type','text/html;charset=utf-8')])

file_name = env['PATH_INFO']

"""
if file_name == "/index.py":
return index()
elif file_name == "/center.py":
return center()
else:
return "我爱你中国..."
"""
try:
return URL_FUN_DIC[file_name]()
except Exception as e:
return "您访问的页面 %s 不存在" % str(e)
return func()

二、伪静态、静态和动态

1、静态URL

        静态URL类似 域名/news/2012-5-18/110.html 我们一般称为真静态URL,每个网页有真实的物理路径,也就是真实存在服务器里的。

优点是:

        网站打开速度快,因为它不用进行运算;另外网址结构比较友好,利于记忆。

缺点是:

        最大的缺点是如果是中大型网站,则产生的页面特别多,不好管理。至于有的开发者说占用硬盘空间大,我觉得这个可有忽略不计,占用不了多少空间的,况且目前硬盘空间都比较大。还有的开发者说会伤硬盘,这点也可以忽略不计。

一句话总结:
 
        静态网站对SEO的影响:静态URL对SEO肯定有加分的影响,因为打开速度快,这个是本质。

2、动态URL

        动态URL类似 域名/NewsMore.asp?id=5 或者 域名/DaiKuan.php?id=17,带有?号的URL,我们一般称为动态网址,每个URL只是一个逻辑地址,并不是真实物理存在服务器硬盘里的。

优点是:

        适合中大型网站,修改页面很方便,因为是逻辑地址,所以占用硬盘空间要比纯静态网站小。

缺点是:

        因为要进行运算,所以打开速度稍慢,不过这个可有忽略不计,目前有服务器缓存技术可以解决速度问题。最大的缺点是URL结构稍稍复杂,不利于记忆。

一句话总结:

        动态URL对SEO的影响:目前百度SE已经能够很好的理解动态URL,所以对SEO没有什么减分的影响(特别复杂的URL结构除外)。所以你无论选择动态还是静态其实都无所谓,看你选择的程序和需求了。

3、伪静态URL

        伪静态URL类似 域名/course/74.html 这个URL和真静态URL类似。他是通过伪静态规则把动态URL伪装成静态网址。也是逻辑地址,不存在物理地址。

优点是:

        URL比较友好,利于记忆。非常适合大中型网站,是个折中方案。

缺点是:

        设置麻烦,服务器要支持重写规则,小企业网站或者玩不好的就不要折腾了。另外进行了伪静态网站访问速度并没有变快,因为实质上它会额外的进行运算解释,反正增加了服务器负担,速度反而变慢,不过现在的服务器都很强大,这种影响也可以忽略不计。还有可能会造成动态URL和静态URL都被搜索引擎收录,不过可以用robots禁止掉动态地址。

一句话总结:

        对SEO的影响:和动态URL一样,对SEO没有什么减分影响。

4、让web服务器支持伪静态

(1)、修改web-server.py中捕获的请求后缀名



(2)、修改mini_frame.py框架



三、web服务器动态查询MySQL数据库中的数据并展示

1、准备数据库数据

create database stock_db charset=utf8;

use stock_db;

DROP TABLE IF EXISTS `focus`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `focus` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`note_info` varchar(200) DEFAULT '',
`info_id` int(10) unsigned DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `info_id` (`info_id`),
CONSTRAINT `focus_ibfk_1` FOREIGN KEY (`info_id`) REFERENCES `info` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `focus`
--

LOCK TABLES `focus` WRITE;
/*!40000 ALTER TABLE `focus` DISABLE KEYS */;
INSERT INTO `focus` VALUES (2,'你确定要买这个?',36),(3,'利好',37),(9,'',88),(10,'',89),(13,'',1);
/*!40000 ALTER TABLE `focus` ENABLE KEYS */;
UNLOCK TABLES;

--
-- Table structure for table `info`
--

DROP TABLE IF EXISTS `info`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `info` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`code` varchar(6) NOT NULL COMMENT '股票代码',
`short` varchar(10) NOT NULL COMMENT '股票简称',
`chg` varchar(10) NOT NULL COMMENT '涨跌幅',
`turnover` varchar(255) NOT NULL COMMENT '换手率',
`price` decimal(10,2) NOT NULL COMMENT '最新价',
`highs` decimal(10,2) NOT NULL COMMENT '前期高点',
`time` date DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=95 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `info`
--

LOCK TABLES `info` WRITE;
/*!40000 ALTER TABLE `info` DISABLE KEYS */;
INSERT INTO `info` VALUES
(1,'000007','全新好','10.01%','4.40%',16.05,14.60,'2017-07-18'),(2,'000036','华联控股','10.04%','10.80%',11.29,10.26,'2017-07-20'),
(3,'000039','中集集团','1.35%','1.78%',18.07,18.06,'2017-06-28'),(4,'000050','深天马A','4.38%','4.65%',22.86,22.02,'2017-07-19'),
(5,'000056','皇庭国际','0.39%','0.65%',12.96,12.91,'2017-07-20'),(6,'000059','华锦股份','3.37%','7.16%',12.26,12.24,'2017-04-11'),
(7,'000060','中金岭南','1.34%','3.39%',12.08,11.92,'2017-07-20'),(8,'000426','兴业矿业','0.41%','2.17%',9.71,9.67,'2017-07-20'),
(9,'000488','晨鸣纸业','6.30%','5.50%',16.37,15.59,'2017-07-10'),(10,'000528','柳工','1.84%','3.03%',9.42,9.33,'2017-07-19'),
(11,'000540','中天金融','0.37%','5.46%',8.11,8.08,'2017-07-20'),(12,'000581','威孚高科','3.49%','3.72%',27.00,26.86,'2017-06-26'),
(13,'000627','天茂集团','5.81%','12.51%',10.93,10.33,'2017-07-20'),(14,'000683','远兴能源','6.42%','21.27%',3.48,3.29,'2017-07-19'),
(15,'000703','恒逸石化','0.24%','1.65%',16.92,16.88,'2017-07-20'),(16,'000822','山东海化','6.60%','8.54%',9.05,8.75,'2017-07-06'),
(17,'000830','鲁西化工','1.38%','4.80%',7.36,7.26,'2017-07-20'),(18,'000878','云南铜业','1.26%','3.23%',14.50,14.47,'2017-07-19'),
(19,'000905','厦门港务','5.44%','10.85%',15.90,15.60,'2017-04-20'),(20,'000990','诚志股份','0.53%','1.00%',16.99,16.90,'2017-07-20'),
(21,'002019','亿帆医药','1.19%','2.81%',17.05,16.85,'2017-07-20'),(22,'002078','太阳纸业','2.05%','1.90%',8.45,8.29,'2017-07-19'),
(23,'002092','中泰化学','7.25%','6.20%',15.53,14.48,'2017-07-20'),(24,'002145','中核钛白','2.43%','7.68%',6.75,6.61,'2017-07-19'),
(25,'002285','世联行','8.59%','5.66%',9.23,8.50,'2017-07-20'),(26,'002311','海大集团','1.13%','0.24%',18.81,18.63,'2017-07-19'),
(27,'002460','赣锋锂业','9.41%','9.00%',63.70,58.22,'2017-07-20'),(28,'002466','天齐锂业','3.62%',
14068
'3.66%',68.44,66.05,'2017-07-20'),
(29,'002470','金正大','2.30%','0.99%',8.00,7.82,'2017-07-20'),(30,'002496','辉丰股份','3.15%','4.29%',5.24,5.08,'2017-04-10'),
(31,'002497','雅化集团','0.38%','12.36%',13.10,13.05,'2017-07-20'),(32,'002500','山西证券','0.44%','3.70%',11.49,11.44,'2017-07-20'),
(33,'002636','金安国纪','2.70%','11.59%',19.80,19.42,'2017-07-19'),(34,'300032','金龙机电','0.66%','0.72%',15.28,15.18,'2017-07-20'),
(35,'300115','长盈精密','0.60%','0.59%',33.50,33.41,'2017-07-19'),(36,'300268','万福生科','-10.00%','0.27%',31.77,13.57,'2017-04-10'),
(37,'300280','南通锻压','3.31%','0.66%',32.20,32.00,'2017-04-11'),(38,'300320','海达股份','0.28%','0.82%',18.26,18.21,'2017-07-20'),
(39,'300408','三环集团','1.69%','0.81%',23.42,23.17,'2017-07-19'),(40,'300477','合纵科技','2.84%','5.12%',22.10,22.00,'2017-07-12'),
(41,'600020','中原高速','5.46%','4.48%',5.60,5.31,'2017-07-20'),(42,'600033','福建高速','1.01%','1.77%',4.00,3.99,'2017-06-26'),
(43,'600066','宇通客车','4.15%','1.49%',23.08,23.05,'2017-06-13'),(44,'600067','冠城大通','0.40%','2.97%',7.56,7.53,'2017-07-20'),
(45,'600110','诺德股份','2.08%','4.26%',16.16,15.83,'2017-07-20'),(46,'600133','东湖高新','9.65%','21.74%',13.64,12.44,'2017-07-20'),
(47,'600153','建发股份','3.65%','2.03%',13.35,13.21,'2017-07-10'),(48,'600180','瑞茂通','2.20%','1.07%',14.86,14.54,'2017-07-20'),
(49,'600183','生益科技','6.94%','4.06%',14.94,14.12,'2017-07-19'),(50,'600188','兖州煤业','1.53%','0.99%',14.56,14.43,'2017-07-19'),
(51,'600191','华资实业','10.03%','11.72%',15.80,14.36,'2017-07-20'),(52,'600210','紫江企业','6.03%','10.90%',6.68,6.30,'2017-07-20'),
(53,'600212','江泉实业','1.39%','1.78%',10.20,10.15,'2017-07-19'),(54,'600225','*ST松江','4.96%','2.47%',5.71,5.61,'2017-04-13'),
(55,'600230','沧州大化','5.74%','13.54%',43.26,40.91,'2017-07-20'),(56,'600231','凌钢股份','2.79%','3.77%',3.68,3.60,'2017-07-19'),
(57,'600291','西水股份','10.02%','9.23%',34.71,31.55,'2017-07-20'),(58,'600295','鄂尔多斯','4.96%','12.62%',16.51,15.73,'2017-07-20'),
(59,'600303','曙光股份','8.37%','14.53%',11.53,10.64,'2017-07-20'),(60,'600308','华泰股份','1.12%','2.66%',6.30,6.26,'2017-07-19'),
(61,'600309','万华化学','0.03%','1.78%',31.81,31.80,'2017-07-20'),(62,'600352','浙江龙盛','0.39%','1.85%',10.32,10.28,'2017-07-20'),
(63,'600354','敦煌种业','7.89%','18.74%',9.44,8.75,'2017-07-20'),(64,'600408','安泰集团','1.98%','3.38%',4.13,4.12,'2017-04-13'),
(65,'600409','三友化工','0.62%','3.78%',11.36,11.29,'2017-07-20'),(66,'600499','科达洁能','0.46%','3.94%',8.84,8.80,'2017-07-20'),
(67,'600508','上海能源','3.26%','2.99%',13.32,13.01,'2017-07-19'),(68,'600563','法拉电子','0.32%','1.36%',53.67,53.50,'2017-07-20'),
(69,'600567','山鹰纸业','0.76%','2.85%',3.98,3.96,'2017-07-19'),(70,'600585','海螺水泥','0.45%','0.61%',24.51,24.44,'2017-07-19'),
(71,'600668','尖峰集团','4.35%','6.43%',18.70,18.36,'2017-04-13'),(72,'600688','上海石化','2.72%','0.91%',6.80,6.74,'2017-06-01'),
(73,'600729','重庆百货','5.70%','3.34%',27.45,27.13,'2017-06-29'),(74,'600739','辽宁成大','3.30%','3.50%',19.74,19.11,'2017-07-20'),
(75,'600779','水井坊','3.85%','2.77%',29.39,28.30,'2017-07-20'),(76,'600781','辅仁药业','8.61%','4.16%',23.46,21.89,'2017-05-02'),
(77,'600801','华新水泥','4.00%','10.15%',12.99,12.49,'2017-07-20'),(78,'600846','同济科技','2.06%','17.41%',9.39,9.26,'2017-04-13'),
(79,'600884','杉杉股份','1.08%','3.53%',20.67,20.45,'2017-07-20'),(80,'600966','博汇纸业','2.89%','5.54%',6.41,6.28,'2017-07-19'),
(81,'600971','恒源煤电','2.36%','8.81%',12.16,11.88,'2017-07-20'),(82,'601012','隆基股份','0.76%','1.30%',19.93,19.78,'2017-07-20'),
(83,'601100','恒立液压','4.78%','0.92%',19.31,18.97,'2017-07-13'),(84,'601101','昊华能源','4.03%','6.06%',11.10,10.80,'2017-07-19'),
(85,'601216','君正集团','2.16%','2.26%',5.20,5.10,'2017-04-17'),(86,'601666','平煤股份','2.81%','6.14%',6.96,6.77,'2017-07-20'),
(87,'601668','中国建筑','2.39%','1.42%',10.70,10.45,'2017-07-20'),(88,'601678','滨化股份','0.13%','2.47%',7.92,7.91,'2017-07-20'),
(89,'601918','新集能源','1.23%','3.11%',4.93,4.92,'2017-07-19'),(90,'603167','渤海轮渡','2.77%','3.34%',11.87,11.61,'2017-04-13'),
(91,'603369','今世缘','3.34%','2.13%',14.24,13.78,'2017-07-20'),(92,'603589','口子窖','3.99%','1.84%',39.37,39.04,'2017-06-26'),
(93,'603799','华友钴业','2.38%','7.19%',67.46,65.89,'2017-07-20'),(94,'603993','洛阳钼业','2.94%','2.50%',7.36,7.16,'2017-07-19');

2、修改mini_frame.py内容

# coding=UTF-8
import re
from pymysql import connect

URL_FUN_DIC = dict()

def route(url):
def set_func(func):
# 在执行装饰的过程中将参数添加到字典中
URL_FUN_DIC[url] = func
def call_func(*args, **kwargs):
return func(*args, **kwargs)
return call_func
return set_func

@route("/index.html")
def index():
with open("./templates/index.html") as f:

content = f.read()

# 从数据库中将数据查询出来
conn = connect(host='localhost', port=3306, user='root', password='mysql', database='stock_db',
charset='utf8')
# 获得cursor对象
cs = conn.cursor()
cs.execute("select * from info;")

stock_info_list = cs.fetchall()
cs.close()
conn.close()

#按照页面要求的格式组装数据
tr_template = """<tr>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>
<input type="button" value="添加" id="toAdd" name="toAdd" systemidvaule="%s">
</td>
</tr>
"""

# 使用正则表达式替换源模版中的数据

from_mysql_data = ""

for data in stock_info_list:
from_mysql_data += tr_template %(data[0],data[1],data[2],data[3],data[4],data[5],data[6],data[7],data[1])

# 使用正则表达式替换源模版中的数据

# from_mysql_data = "这里以后放的是从数据库中查询出来的数据"

content = re.sub(r"\{%content%\}", from_mysql_data, content)

return content

@route("/center.html")
def center():
with open("./templates/center.html") as f:

content = f.read()

# 从数据库中将数据查询出来
conn = connect(host='localhost', port=3306, user='root', password='mysql', database='stock_db',
charset='utf8')
# 获得cursor对象
cs = conn.cursor()
cs.execute("select i.code,i.short,i.chg,i.turnover,i.price,i.highs,f.note_info from info as i inner join focus as f on i.id=f.info_id;")

stock_info_list = cs.fetchall()
cs.close()
conn.close()

#按照页面要求的格式组装数据
tr_template = """<tr>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>
<a type="button" class="btn btn-default btn-xs" href="/update/%s.html"> <span class="glyphicon glyphicon-star" aria-hidden="true"></span> 修改 </a>
</td>
<td>
<input type="button" value="删除" id="toDel" name="toDel" systemidvaule="%s">
</td>
</tr>
"""

# 使用正则表达式替换源模版中的数据

from_mysql_data = ""

for data in stock_info_list:
from_mysql_data += tr_template %(data[0],data[1],data[2],data[3],data[4],data[5],data[6],data[0],data[0])

# 使用正则表达式替换源模版中的数据

# from_mysql_data = "这里以后放的是从数据库中查询出来的数据"

content = re.sub(r"\{%content%\}", from_mysql_data, content)

return content

def application(env, start_response):
start_response('200 OK', [('Content-Type','text/html;charset=utf-8')])

file_name = env['PATH_INFO']

"""
if file_name == "/index.py":
return index()
elif file_name == "/center.py":
return center()
else:
return "我爱你中国..."
"""
try:
return URL_FUN_DIC[file_name]()
except Exception as e:
return "您访问的页面 %s 不存在" % str(e)
return func()

四、mini_frame.py框架路由支持正则

1、修改mini_frame.py代码



@route(r"/add/\d+\.html")
def add_func():
return "ADD 0K...."

def application(env, start_response):
start_response('200 OK', [('Content-Type','text/html;charset=utf-8')])

file_name = env['PATH_INFO']

"""
if file_name == "/index.py":
return index()
elif file_name == "/center.py":
return center()
else:
return "我爱你中国..."
"""
try:
# return URL_FUN_DIC[file_name]()
"""
使用正则表达式当作装饰器的参数之后,字典中的数据如下:

{
"/index.html":index,
"/center.html"center,
r"/add/\d+\.html":add_func
}

使用item()方法进行遍历,取出每一个url和func

"""
for url, func in URL_FUN_DIC.items():
ret = re.match(url, file_name)
if ret:
return func()
else:
return "请求的页面 %s 不存在" % file_name

except Exception as e:
return "您访问的页面 %s 不存在" % str(e)
return func()

2、实现添加关注功能

# coding=UTF-8
import re
from pymysql import connect

URL_FUN_DIC = dict()

def route(url):
def set_func(func):
# 在执行装饰的过程中将参数添加到字典中
URL_FUN_DIC[url] = func
def call_func(*args, **kwargs):
return func(*args, **kwargs)
return call_func
return set_func

@route("/index.html")
def index(ret):
with open("./templates/index.html") as f:

content = f.read()

# 从数据库中将数据查询出来
conn = connect(host='localhost', port=3306, user='root', password='mysql', database='stock_db',
charset='utf8')
# 获得cursor对象
cs = conn.cursor()
cs.execute("select * from info;")

stock_info_list = cs.fetchall()
cs.close()
conn.close()

#按照页面要求的格式组装数据
tr_template = """<tr>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>
<input type="button" value="添加" id="toAdd" name="toAdd" systemidvaule="%s">
</td>
</tr>
"""

# 使用正则表达式替换源模版中的数据

from_mysql_data = ""

for data in stock_info_list:
from_mysql_data += tr_template %(data[0],data[1],data[2],data[3],data[4],data[5],data[6],data[7],data[1])

# 使用正则表达式替换源模版中的数据

# from_mysql_data = "这里以后放的是从数据库中查询出来的数据"

content = re.sub(r"\{%content%\}", from_mysql_data, content)

return content

@route("/center.html")
def center(ret):
with open("./templates/center.html") as f:

content = f.read()

# 从数据库中将数据查询出来
conn = connect(host='localhost', port=3306, user='root', password='mysql', database='stock_db',
charset='utf8')
# 获得cursor对象
cs = conn.cursor()
cs.execute("select i.code,i.short,i.chg,i.turnover,i.price,i.highs,f.note_info from info as i inner join focus as f on i.id=f.info_id;")

stock_info_list = cs.fetchall()
cs.close()
conn.close()

#按照页面要求的格式组装数据
tr_template = """<tr>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>
<a type="button" class="btn btn-default btn-xs" href="/update/%s.html"> <span class="glyphicon glyphicon-star" aria-hidden="true"></span> 修改 </a>
</td>
<td>
<input type="button" value="删除" id="toDel" name="toDel" systemidvaule="%s">
</td>
</tr>
"""

# 使用正则表达式替换源模版中的数据

from_mysql_data = ""

for data in stock_info_list:
from_mysql_data += tr_template %(data[0],data[1],data[2],data[3],data[4],data[5],data[6],data[0],data[0])

# 使用正则表达式替换源模版中的数据

# from_mysql_data = "这里以后放的是从数据库中查询出来的数据"

content = re.sub(r"\{%content%\}", from_mysql_data, content)

return content

@route(r"/add/(\d+)\.html")
def add_func(ret):
# 获取第一个分组(股票的code)
stock_code = ret.group(1)

# 判断当前股票是否存在
conn = connect(host='localhost', port=3306, user='root', password='mysql', database='stock_db', charset='utf8')
# 获取游标
cs = conn.cursor()
sql = """select * from info where code = %s"""
cs.execute(sql, (stock_code,))
# 如果没有当前代码,提示并return
if not cs.fetchone():
cs.close()
conn.close()
return "没有这只股票,请重试"

# 判断当前选中的股票是否已经关注过
sql = """select * from info as i inner join focus as f on i.id=f.info_id where i.code = %s"""
cs.execute(sql, stock_code)
# 如果已经关注了当前代码,提示并return
if cs.fetchone():
cs.close()
conn.close()
return "您已经关注过这只股票,请勿重复关注"

# 可以开始关注操作,添加关注
sql = """insert into focus(info_id) select id from info where code=%s"""
cs.execute(sql, stock_code)
conn.commit()
cs.close()
conn.close()

return "关注 成功 .... "

def application(env, start_response):
start_response('200 OK', [('Content-Type','text/html;charset=utf-8')])

file_name = env['PATH_INFO']

"""
if file_name == "/index.py":
return index()
elif file_name == "/center.py":
return center()
else:
return "我爱你中国..."
"""
try:
# return URL_FUN_DIC[file_name]()
"""
使用正则表达式当作装饰器的参数之后,字典中的数据如下:

{
"/index.html":index,
"/center.html"center,
r"/add/\d+\.html":add_func
}

使用item()方法进行遍历,取出每一个url和func

"""
for url, func in URL_FUN_DIC.items():
ret = re.match(url, file_name)
if ret:
return func(ret)
else:
return "请求的页面 %s 不存在" % file_name

except Exception as e:
return "您访问的页面 %s 不存在" % str(e)
return func()

3、实现取消关注的功能



@route(r"/del/(\d+)\.html")
def add_func(ret):
# 获取第一个分组(股票的code)
stock_code = ret.group(1)

# 判断当前股票是否存在
conn = connect(host='localhost', port=3306, user='root', password='mysql', database='stock_db', charset='utf8')
# 获取游标
cs = conn.cursor()
sql = """select * from info where code = %s"""
cs.execute(sql, (stock_code,))
# 如果没有当前代码,提示并return
if not cs.fetchone():
cs.close()
conn.close()
return "没有这只股票,请重试"

# 判断当前选中的股票是否已经关注过
sql = """select * from info as i inner join focus as f on i.id=f.info_id where i.code = %s"""
cs.execute(sql, stock_code)
# 如果没有关注当前代码,提示并return
if not cs.fetchone():
cs.close()
conn.close()
return "您没有关注过这只股票,取消失败"

# 可以开始取消关注操作,删除关注
sql = """delete from focus where info_id = (select id from info where code=%s)"""
cs.execute(sql, stock_code)
conn.commit()
cs.close()
conn.close()

return "取消关注 成功 .... "

4、实现更新股票备注信息的功能



@route(r"/update/(\d+)\.html")
def to_update_view(ret):
"""跳转到修改数据的页面"""
# 获取股票code
stock_code = ret.group(1)

# 打开模版页面
with open("./templates/update.html") as f:
content = f.read()

# 根据股票代码查询相关数据
conn = connect(host='localhost', port=3306, user='root', password='mysql', database='stock_db', charset='utf8')
cs = conn.cursor()
sql = """select f.note_info from focus as f inner join info as i on i.id=f.info_id where i.code=%s;"""
cs.execute(sql, stock_code)
stock_infos = cs.fetchone()
note_info = stock_infos[0] # 获取当前股票的备注信息,用于页面回显
cs.close()
conn.close()

# 替换html页面中的数据
content = re.sub(r"\{%note_info%\}", note_info, content)
content = re.sub(r"\{%code%\}", stock_code, content)
return content

@route(r"/update/(\d+)/(.*)\.html")
def update_stock(ret):
"""修改股票信息"""
stock_code = ret.group(1)
comment = ret.group(2)

conn = connect(host='localhost', port=3306, user='root', password='mysql', database='stock_db', charset='utf8')
cs = conn.cursor()
sql = """update focus set note_info=%s where info_id = (select id from info where code = %s)"""
cs.execute(sql, (comment, stock_code))
conn.commit()
cs.close()
conn.close()

return "修改成功..."

5、url中有输入非字母时的URL解码

(1)、抛出问题

        当修改的备注信息中有特殊字符或者中文的时候,出现一下情况



解决方案:使用python中的 urllib.parse 模块进行编、解码

(2)、导入urllib.parse模块

import urllib.parse

(3)、修改保存备注信息的方法

# 数据使用URL编码
urllib.parse,quote(字符串)

# 将URL编码方式的字符串进行解码
urllib.parse.unquote(url编码方式的字符串)



五、Log日志

1、日志级别

日志一共分成5个等级,从到高分别是:DEBUG    INFO    WARNING    ERROR    CRITICAL

说明:

        DEBUG:详细的信息,通常只出现在诊断问题上

        INFO:确认一切按预期运行

        WARNING:一个迹象表明,一些意想不到的事情发生了,或表明一些问题在不久的将来(例如。磁盘空间低”)。这个软件还能按预期工作。

        ERROR:更严重的问题,软件没能执行一些功能

        CRITICAL:一个严重的错误,这表明程序本身可能无法继续运行

这5个等级,也分别对应5种打日志的方法: debug 、info 、warning 、error 、critical。默认的是WARNING,当在WARNING或之上时才被跟踪。

2、日志输出

有两种方式记录跟踪,一种输出控制台,另一种是记录到文件中,如日志文件。

(1)、将日志输出到控制台

# 导入log日志模块
import logging

"""
设置默认日志等级,格式化要输出的内容
"""
logging.basicConfig(level=logging.WARNING,
format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s')

# 开始使用log功能
logging.info('这是 loggging info message')
logging.debug('这是 loggging debug message')
logging.warning('这是 loggging a warning message')
logging.error('这是 an loggging error message')
logging.critical('这是 loggging critical message')

"""
输出结果:
2018-03-25 19:51:38,525 - 模拟京东查询.py[line:9] - WARNING: 这是 loggging a warning message
2018-03-25 19:51:38,526 - 模拟京东查询.py[line:10] - ERROR: 这是 an loggging error message
2018-03-25 19:51:38,527 - 模拟京东查询.py[line:11] - CRITICAL: 这是 loggging critical message

只有是WARNING以上的日志等级才会输出,因为设置了默认等级为 WARNING
"""

说明:

        通过logging.basicConfig函数对日志的输出格式及方式做相关配置,上面代码设置日志的输出等级是WARNING级别,意思是WARNING级别以上的日志才会输出。另外还制定了日志输出的格式。

        注意,只要用过一次log功能再次设置格式时将失效,实际开发中格式肯定不会经常变化,所以刚开始时需要设定好格式。

(2)、将日志输出到日志文件

将日志输出到文件,只需要在logging.basicConfig函数中设置好输出文件的文件名和写文件的模式。

import logging

logging.basicConfig(level=logging.WARNING,
filename='./log.txt', # 设置文件的名称以及位置
filemode='w', # 设置打开日志文件的方式
format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s')
# use logging
logging.info('这是 loggging info message')
logging.debug('这是 loggging debug message')
logging.warning('这是 loggging a warning message')
logging.error('这是 an loggging error message')
logging.critical('这是 loggging critical message')

(3)、将日志输出到控制台和日志文件

import logging

# 第一步,创建一个logger
logger = logging.getLogger()
logger.setLevel(logging.INFO) # 设置日志的等级等级总开关

# 第二步,创建一个handler对象,用于写入日志文件
logfile = './log.txt'
fh = logging.FileHandler(logfile, mode='a') # open的打开模式这里可以进行参考
fh.setLevel(logging.DEBUG) # 输出到file的log等级的开关

# 第三步,再创建一个handler,用于输出到控制台
ch = logging.StreamHandler()
ch.setLevel(logging.WARNING) # 输出到console的log等级的开关

# 第四步,定义日志信息的输出格式
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')

3、日志格式说明

logging.basicConfig函数中,可以指定日志的输出格式format,这个参数可以输出很多有用的信息,如下:

        %(levelno)s: 打印日志级别的数值

       %(levelname)s: 打印日志级别名称

       %(pathname)s: 打印当前执行程序的路径,其实就是sys.argv[0]

       %(filename)s: 打印当前执行程序名

       %(funcName)s: 打印日志的当前函数

       %(lineno)d: 打印日志的当前行号

       %(asctime)s: 打印日志的时间

       %(thread)d: 打印线程ID

       %(threadName)s: 打印线程名称

       %(process)d: 打印进程ID

       %(message)s: 打印日志信息
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: