06python入门—文件、异常、日志

文件

关键字with 在不再需要访问文件后将其关闭。 在这个程序中, 注意到我们调用了open() , 但没有调用close() ; 你也可以调用open() 和close() 来打开和关闭文件, 但这样做时, 如果程序存在bug, 导致close() 语句未执行, 文件将不会关闭。 这看似微不足道, 但未妥善地关闭文件可能会导致数据丢失或受损

with open('pi_digits.txt') as file_object:
	contents = file_object.read()
	print(contents)
	print(contents.rstrip())

相比于原始文件, 该输出唯一不同的地方是末尾多了一个空行。 为何会多出这个空行呢? 因为read() 到达文件末尾时返回一个空字符串, 而将这个空字符串显示出来时就是一个空行。 要删除多出来的空行, 可在print 语句中使用rstrip()

逐行读取

filename = 'pi_digits.txt'
with open(filename) as file_object:
	for line in file_object:
	print(line.rstrip())

写文件

函数write() 不会在你写入的文本末尾添加换行符, 因此如果你写入多行时没有指定换行符, 文件看起来可能不是你希望的那样

filename = 'programming.txt'
with open(filename, 'w') as file_object:
	file_object.write("I love programming.")

异常

发生错误时, 如果程序还有工作没有完成, 妥善地处理错误就尤其重要。 这种情况经常会出现在要求用户提供输入的程序中; 如果程序能够妥善地处理无效输入, 就能再提示用户提供有效输入, 而不至于崩溃。

try:
print(5/0)
except ZeroDivisionError:
print("You can't divide by zero!")

else

print("Give me two numbers, and I'll divide them.")
print("Enter 'q' to quit.")
while True:
first_number = input("\nFirst number: ")
if first_number == 'q':
break
second_number = input("Second number: ")
try:
	answer = int(first_number) / int(second_number)
except ZeroDivisionError:
	print("You can't divide by 0!")
else:
	print(answer)
finally:
	print('last')

如果除法运算成功, 我们就执行else 代码块
不管是否成功都会执行finally后的语句

初识logging

import logging  

# 创建一个logger  
logger = logging.getLogger('mylogger')  
logger.setLevel(logging.DEBUG)  

# 创建一个handler,用于写入日志文件  
fh = logging.FileHandler('test.log')  
fh.setLevel(logging.DEBUG)  

# 再创建一个handler,用于输出到控制台  
ch = logging.StreamHandler()  
ch.setLevel(logging.DEBUG)  

# 定义handler的输出格式  
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')  
fh.setFormatter(formatter)  
ch.setFormatter(formatter)  

# 给logger添加handler  
logger.addHandler(fh)  
logger.addHandler(ch)  

# 记录一条日志  
logger.info('foorbar')

2019-06-23 23:06:11,507 - mylogger - INFO - foorbar

基本概念

  1. Logger 记录器,暴露了应用程序代码能直接使用的接口
  2. Handler 处理器,将(记录器产生的)日志记录发送至合适的目的地。
  3. Filter 过滤器,提供了更好的粒度控制,它可以决定输出哪些日志记录。
  4. Formatter 格式化器,指明了最终输出中日志记录的布局。

logging记录器

Logger是一个树形层级结构,在使用接口debug,info,warn,error,critical之前必须创建Logger实例,即创建一个记录器,如果没有显式的进行创建,则默认创建一个root logger,并应用默认的日志级别(warning),处理器Handler(默认为StreamHandler,即将日志信息打印输出在标准输出上),格式化器Formatter(默认的格式即为第一个简单使用程序中输出的格式)。

# 创建logging实例
logger = logging.getLogger(logger_name)
 # 设置日志级别为ERROR,即只有日志级别大于等于ERROR的日志才会输出
logger.setLevel(logging.ERROR) 
# 为Logger实例增加一个处理器
logger.addHandler(handler_name)  
 # 为Logger实例删除一个处理器
logger.removeHandler(handler_name)  

Handler处理器

Handler处理器类型有很多种,比较常用的有三个,StreamHandler,FileHandler,NullHandler

sh = logging.StreamHandler(stream=None)
fh = logging.FileHandler(filename, mode='a', encoding=None, delay=False)

创建处理器后,处理器对象的方法

# 指定日志级别,低于WARN级别的日志将被忽略
ch.setLevel(logging.WARN) 
 # 设置一个格式化器formatter 
ch.setFormatter(formatter_name)
 # 增加一个过滤器,可以增加多个
ch.addFilter(filter_name)
# 删除一个过滤器
ch.removeFilter(filter_name)  

Format格式化器

使用Formatter对象设置日志信息的输出规则、结构和内容,默认的时间格式为%Y-%m-%d %H:%M:%S。

formatter = logging.Formatter(fmt=None, datefmt=None)
# fmt是消息的格式化字符串,datefmt是日期字符串。如果不指明fmt,将使用'%(message)s'。如果不指明datefmt,将使用ISO8601日期格式。


#定义Formatter
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
#为Handler添加Formatter
fh.setFormatter(formatter)
ch.setFormatter(formatter

Filter过滤器

限制只有满足过滤规则的日志才会输出。
比如我们定义了filter = logging.Filter(‘a.b.c’),并将这个Filter添加到了一个Handler上,则使用该Handler的Logger中只有名字带a.b.c前缀的Logger才能输出其日志。

filter = logging.Filter(name='')

多模块使用logging

logging模块保证在同一个python解释器内,多次调用logging.getLogger(‘log_name’)都会返回同一个logger实例,即使是在多个模块的情况下。所以典型的多模块场景下使用logging的方式是在main模块中配置logging,这个配置会作用于多个的子模块,然后在其他模块中直接通过getLogger获取Logger对象即可。
main

import logging  
import logging.config  
  
logging.config.fileConfig('logging.conf')  
root_logger = logging.getLogger('root')  
root_logger.debug('test root logger...')  
  
logger = logging.getLogger('main')  
logger.info('test main logger')  
logger.info('start import module \'mod\'...')  
import mod  
  
logger.debug('let\'s test mod.testLogger()')  
mod.testLogger()  
  
root_logger.info('finish test...') 

子模块mod.py

import logging  
import submod  
  
logger = logging.getLogger('main.mod')  
logger.info('logger of mod say something...')  
  
def testLogger():  
    logger.debug('this is mod.testLogger...')  
    submod.tst() 

子模块submod.py

import logging  
  
logger = logging.getLogger('main.mod.submod')  
logger.info('logger of submod say something...')  
  
def tst():  
    logger.info('this is submod.tst()...')  
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值