文件
关键字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
基本概念
- Logger 记录器,暴露了应用程序代码能直接使用的接口
- Handler 处理器,将(记录器产生的)日志记录发送至合适的目的地。
- Filter 过滤器,提供了更好的粒度控制,它可以决定输出哪些日志记录。
- 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()...')