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

一、给路由添加正则表达式

  • 给路由参数添加正则表达式的原因:在实际开发时,url中往往会带有很多的参数,例如:/add/0003.html 中0003 就是参数,如果没有正则的话,那么就需要编写 N@route 来进行添加 url 对应的函数到字典中,此时字典中的键值对有 N 个,浪费空间,而采用了正则的话,那么只要编写1@route 就可以完成多个 url 例如/add/0008.html/add/0003.html 等对同一个函数,此时的字典中键值对减少很多,如下示例代码

    import re
    from pymysql import connect
    
    # 定义一个空子典
    URL_FUNC_DICT = dict()
    
    
    def route(url):
            """
            带参数的装饰器来做路由
            :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.判断下是否有这个股票代码
           # 创建Connection连接
           conn = connect(host='域名或者公网IP', port=3306, database='数据库名', user='用户名', password='密码',
                 charset='utf8')
           # 获得Cursor对象
           cursor = conn.cursor()
           sql = """select * from info where code=%s;"""
           cursor.execute(sql,(stock_code,))
    
           print("************-----------1------------------")
    
           # 如果要是没有这个股票代码,那么就认为是非法的请求
           if not cursor.fetchone():
                cursor.close()
                conn.close()
                return "没有这支股票,大哥 ,我们是创业公司,请手下留情..."
    
           print("************-----------2------------------")
    
           # 3.在股票存在的情况下查看股票是否关注过
           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,))
           # 如果查出来表示关注过
           if cursor.fetchone():
                 cursor.close()
                 conn.close()
                 return "已经关注过了,请勿重复关注..."
    
           print("************-----------3------------------")
    
          # 4.在没有关注的情况下,进行关注,也就是往关注的信息表里面添加数据
          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 "关注成功"
    
    
    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)没有对应的函数...." % file_name
    
            except Exception as ret:
                 return "产生了异常:%s"% str(ret)
    

二、url 编码

  • 2.1、python3对url编解码
    导入库 urllib.parse

    import urllib.parse
    

    Python3 url编码

    print(urllib.parse.quote("不忘初心,方得始终!"))
    打印结果:%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'))
    打印结果是:不忘初心,方得始终!
    

    完整的代码如下:

    import urllib.parse
    
    text = urllib.parse.quote("不忘初心,方得始终!")
    
    print("url编码后的文字=%s"%text)
    
    text = urllib.parse.unquote(text)
    
    print("url解码后的文字=%s"%text)
    
  • 2.2、浏览器往服务器传内容的时候会对内容进行编码,如果我们的框架在接收到消息后不进行解码直接写入数据库,我们服务器里面存的是url编码的内容,所以我们需要对内容进行解码,再存到数据库,这样下次读取出来的时候不再是url编码的内容

三、logging日志模块

  • 3.1、开发过程中出现bug是必不可免的,你会怎样debug?从第1行代码开始看么?还是有个文件里面记录着哪里错了更方便呢!!!log日志,Python中有个logging模块可以完成相关信息的记录,在debug时用它往往事半功倍

  • 3.2、日志级别:日志一共分成5个等级,从 低到高 分别是:

    DEBUG      # 调试模式
    INFO       # 确认一切按预期运行
    WARNING    # 警告
    ERROR      # 错误
    CRITICAL   # critical 英[ˈkrɪtɪkl]  严重的;
    

    解释:

    • DEBUG:详细的信息,通常只出现在诊断问题上
    • INFO:确认一切按预期运行
    • WARNING:一个迹象表明,一些意想不到的事情发生了,或表明一些问题在不久的将来(例如。磁盘空间低”)。这个软件还能按预期工作。
    • ERROR:更严重的问题,软件没能执行一些功能
    • CRITICAL:一个严重的错误,这表明程序本身可能无法继续运行
    • 总结:这5个等级,也分别对应5种打日志的方法: debug 、info 、warning 、error 、critical。默认的是WARNING,当在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")
      

      打印结果如下:

      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 行数 、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")
      

      运行后会生成一个 log.txt 文件

      运行后会生成一个 `log.txt` 文件

    • (3)、既要把日志输出到控制台, 还要写入日志文件
      这就需要一个叫作 Logger 的对象来帮忙,下面将对他进行详细介绍,现在这里先学习怎么实现把日志既要输出到控制台又要输出到文件的功能。

      import logging  
      
      # 第一步,创建一个logger  
      logger = logging.getLogger()  
      logger.setLevel(logging.DEBUG)  # Log等级总开关  
      
      # 第二步,创建一个handler,用于写入日志文件  
      logfile = './log.txt'  
      fh = logging.FileHandler(logfile, mode='a')  # open的打开模式这里可以进行参考
      fh.setLevel(logging.INFO)  # 输出到file的log等级的开关  
      
      # 第三步,再创建一个handler,用于输出到控制台  
      ch = logging.StreamHandler()  
      ch.setLevel(logging.WARNING)   # 输出到console的log等级的开关  
      
      # 第四步,定义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')
      

      运行时终端的输出结果:

      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 中,有如下数据:

      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函数中,可以指定日志的输出格式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: 打印日志信息
      
    • 在工作中给的常用格式如下:

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

      这个格式可以输出日志的打印时间,是哪个模块输出的,输出的日志级别是什么,以及输入的日志内容。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 201,552评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,666评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,519评论 0 334
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,180评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,205评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,344评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,781评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,449评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,635评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,467评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,515评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,217评论 3 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,775评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,851评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,084评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,637评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,204评论 2 341

推荐阅读更多精彩内容

  • From:Python之日志处理(logging模块) - 云游道士 - 博客园 https://www.cnbl...
    vigny的先生阅读 2,669评论 3 5
  • 前言 在自动化测试实践过程中,必不可少的就是进行日志管理,方便调试和生产问题追踪,python提供了logg...
    苦叶子阅读 804评论 0 0
  • 常用模块 认识模块 什么是模块 什么是模块? 常见的场景:一个模块就是一个包含了python定义和声明的文件,文...
    go以恒阅读 1,930评论 0 6
  • 这是标题 这是标题 这是标题 这是标题 这是标题 -列表第一项-列表第二项1.有序列表第一项2.有序列表第二项百度...
    Dizoo阅读 304评论 0 0
  • 喜欢配色,窗帘色调也很和谐。但是1:穿衣镜的地方更喜欢搭成一个简易迷你隔断区出来2:入户空间实用性不好, 客餐厅全...
    TheraZhao阅读 471评论 2 8