屋子里休息

2018/03/10 休息

Posted by WangXiaoDong on March 10, 2018
    今天是周六,在宿舍休息了一上午。下午,感觉要赶快看看书总结一下了,否则周末感觉太颓废了!下午,仔细
思考了一下程序的异常处理,回忆复习了一下最近学习的python的日志处理,闭包,生成器函数和装饰器,然后就准备
看会日志相关的书籍。这时候,腾飞邀请我去生命科学院地铁站吃饭。我使用地图搜了一下,发现距离实在是太远了,
不想动!最后,我和腾飞商量,让他们来我这里所里面的食堂吃饭。哎,我真是太懒了,然后我继续看书等他们到来。
    到了大概下午5点多的时候,腾飞过来了,我们一起在食堂里吃了顿饭,感觉食堂的鱼挺好吃的,吃完饭后,腾飞给
我带了一同椰子粉,我非常感动,然后他还跟我聊了很多,让我感到腾飞真的是非常忙碌,每天都会干很多事。
    总结一下腾飞的工作:一个大课题的总秘书,一个小课题的研究者,以后我一定要向腾飞多多学习!

python异常处理和日志处理

今天,总结一下最近编程使用的python异常处理和日志处理的感受,其实异常处理是程序编写时非常重要 的一块,但是我一开始学的语言是C++,这门语言中没有强制要求使用try...catch语句,因此我通常 编写代码的时候忽略了这一块,直到开始学习java的时候,发现好多时候编写代码必须加上try...catch 模块,然而我每次都不深入理解,仅仅使用eclipse自动补全功能加上try...catch模块,或者直接在类上 加入throws Exception最省事,完全不用思考。最近在编写python代码的时候,发现python好多代码也有 try...catch模块,实在是不想再继续不理解了,于是自己思考了一下。

python异常处理

python的异常处理代码很简单,如下所示:

try:
    ...(可能出现异常的代码)
except ...(Python内置异常类或者自己实现的异常类) as e:  (或者直接except:) 
    ...(处理该异常的代码)

我平常根本不管异常处理,什么异常都直接不管,因为控制台会打印出现异常的那一行,然后如果出现错误, 我就根据那一行仔细思考可能出现的逻辑错误。今天,我仔细思考了一下,我这样做会出现两个主要问题:

  1. 任何错误都会导致程序中断
  2. 错误提示不明显,找错误的时间变长

解释:

问题1:我之所以总是忽略该问题,因为我平常编的程序都是比较小的程序,有异常就中断没什么影响,但是如果未来 我跟别人合作,编写一个模块的程序,如果每次我这个模块出现异常,整个程序就中断,那么后果不堪设想!

问题2:为了解释问题2,我们举一个例子。假如我要处理一个日志文件,里面的内容如下:

Jul 16 03:27:01 node69 sced[22053]: Connection from 
Jul 16 03:27:01 node69 sced[22053]: SSH: Server;Ltype 
Jul 16 03:27:01 node69 sced[22053]: SSH: Server;Ltype
Jul 16 03:27:11 node69 sced[23417]: Connection from 
Jul 16 03:27:11 node69 sced[23417]: Connection from 
Jul 16 03:27:11 node69 sced[23417]: SSH: Server;Ltype
Jul 16 03:27:11 node69 sced[23417]: SSH: Server;Ltype
Jul 16 03:27:20 node69 sced[23454]: Connection from 
Jul 16 03:27:20 node69 sced[23454]: Connection from 

我的目标是提取每行字符串里面的sced这个名字,显然,使用python一句话即可:

s = line.split()[4].split('[')[0].strip(':')

这样做没错,但是日志文件通常会很多,比如一共有百万行的日志,而且可能会出现错误,比如空行,或者 有些日志输出的只有一半的行,如下所示:

Jul 16 03:27:01 node69 sced[22053]: SSH: Server;Ltype
(空行)
Jul 16 03:27:11 node69 sced[23417]: Connection from 
Jul 16 03:27:11 node69 sced[23417]: Connection from 
Jul 16 03:27:11 (只有一半的行)
Jul 16 03:27:11 node69 sced[23417]: SSH: Server;Ltype

这样在处理的时候,就会抛出数组越界异常,同时程序中断,每次我遇到问题,总是自己思考怎么回事,但是 如果不知道异常的那一行什么样子,我自己思考总是花费很长时间!而且每次解决一个问题,下次再出现另一个 问题的时候,又要重复这个过程!如果我能一次从头到尾处理这些数据,遇到问题将问题的那行打印出来,然后 程序还能够不中断该多好!显然,异常语句就应运而生!,代码如下:

with open(fileName, 'r',encoding = 'utf-8' ,errors='ignore') as f:
    for line in f.readlines():
        try:
            s = line.split()[4]
            s = s.split('[')[0].strip(':')
            theDict[s] = 1 if theDict.get(s,-1) == -1 else theDict[s]+1    #先得到日志的程序名出现次数的字典
        except:
            logging.exception('文件--' + fileName+'--在解析句子--'+line+'--时出现异常')   #exception代表打印时也会打印出系统错误提示语句
#           raise

一开始,我不知道会遇到什么异常的情况,就把异常打印出来,然后不抛出raise,如果你想要出现异常,后面的数据都不处理了, 那就把raise注释去掉,我感觉raise就像程序中的return的作用。 我的目标是运行一次,把所有可能的没法处理的情况的行都打印出来,如上述的写法,就实现了这个功能,可见,异常处理的语句 多么有用。

总结一下:

编程本质就是实现某个逻辑,但是你没法把逻辑的所有情况都考虑到,此时加上异常处理模块,将异常打印出来,这样就 能在出现异常时将异常的数据提取处理,根据这些数据继续改进自己的程序的逻辑!