本节案例代码主要是对日志文件中新写入的数据进行提取分析,过滤出影响安全的数据并发出警告,数据恢复正常时则接触警报,样例的代码如下:
import timedef read_lastline(filename):with open(filename, 'r') as f:line_=f.seek(0,2)print(line_)while True:line_content=f.readline()if not line_content:time.sleep(0.5)continueyield line_contentdef show(line_content):fields = line_content.split('\t')if ((fields[3] == '瓦斯' or fields[3] == 'CO') and fields[5][0:5] == '越上限报警'):print('警报!!!', fields[4], ':', fields[3], fields[5][0:-1], '发生时间:', fields[0][0:], ',请立即处理!')if ((fields[3] == '瓦斯' or fields[3] == 'CO') and fields[5][0:4] == '报警解除'):print('通告!', fields[4], ':', fields[3], '超值危险报警解除,解除时间:', fields[0][0:])if __name__ == '__main__':for line in read_lastline('safe.log'):if line.strip() !='':show(line)
代码 | 解释 |
with open(filename, 'r') as f: | 以只读方式打开 filename 文件,并把文件对象命名为 f,在代码块结束后自动关闭文件,常用的文件打开形式。 |
line_=f.seek(0,2) | 这里的f就是上述命名后的文件调用,seek()函数一般为seek(offset,intval),功能是将文件的读取指针移动到指定位置,参数offset代表偏移量,intval代表位置,0代表文件开头,1代表当前读取指针位置,2代表文件末尾,这里就代表文件的末尾,实时监测。 |
while True: | 无限循环,死循环 |
line_content = f.readline() | 从当前的指针位置开始读取一行 |
if not line_content: time.sleep(0.5) continue | if not line_content:等价于if line_content == '':代表如果没有读取到文本 time.sleep(0.5) 代表让程序暂停0.5s,避免cpu一直占用进行读取。 Continue代表跳过本次循环的剩余代码,也就自动跳过了yield语句,之后再次开始循环,直到读取到内容,if not line_content:判断失败后开始执行yield语句 这段代码其实很关键,注意continue的缩进在if后面也就是属于if语句,如果这里缩进提前,那么即使有内容也会跳过,代码就失效了 |
yield line_content | 生成器函数,代表读取到的代码交出去,并且暂停代码,直到下文中的if语句返回这里提交的内容为止。 |
fields = line_content.split('\t') | 分割读取到的这一行,并且返回为列表形式,分割原则为制表符tab,也就是这里的\t |
fields[5][0:5] | 下文就是对于上面分割后的列表元素的索引判断,需要注意的是列表索引从0开始,这里的fields[5][0:5]代表的是列表中的第6个元素中的0-5个字符是…… |
if line.strip() !='': | 判断日志行去掉空白字符后是否还有有效内容,避免空行导致程序出错。!=代表不等于。 需要注意的是这里虽然用来for函数遍历,但是要注意上面yield提交的为整行,也就是For的遍历以整行为单位,line代表一整行内容 |