在Python里面,当我们要把一段字符串写入到一个文件里面时,我们会这样写:
with open('text.txt', 'w', encoding='utf-8') as f: f.write('我是一段文本')
或者有人不习惯 with
上下文管理,可能会这样写代码:
f = open('text.txt', 'w', encoding='utf-8') f.write('我是一段文本') f.close()
如果我们的代码需要在多个地方写文件,那么每次使用上下文管理确实稍显费时间。
虽然也可以把写文件的操作封装到一个函数里面,不过实际上Python 3的 print
函数就能够直接写文件:
f = open('text.txt', 'w', encoding='utf-8') print('我是一段字符串', file=f) print('我是第二段内容', file=f) print('我是第三段内容', file=f) f.close()
运行效果如下图所示。
这个时候可能有人会说,你这样确实写到文件里面了,可是屏幕上又不显示了啊。我想既在屏幕上显示,又写入文件怎么做呢?
print
函数的 file
参数,可以接受任何一个带有 write
方法的对象。所以我们可以写一个既打印在屏幕,又写入文件的类:
class print_and_write: def __init__(self, file_name): self.f = open(file_name, 'w', encoding='utf-8') def write(self, text): print(text) self.f.write(text) def close(self): self.f.close() f = print_and_write('text.txt') print('第一段', file=f) print('第二段', file=f) print('第三段', file=f)
运行效果如下图所示。
这个时候,有人会问,你写了这么大一堆,我用一个函数3行代码就能搞定:
def print_and_write(file_name, text): print(text) with open(file_name, 'a', encoding='utf-8') as f: f.write(text)
那么你这种方式与我通过函数来实现的方式有什么区别?
我认为,最主要的区别在于扩展性。当你定义一个函数来既显示到屏幕上,又写入文件的时候。如果现在希望把这个内容再发送到一个HTTP服务中,那么你就需要修改这个函数。随着需求量的增大,你这个函数会越来越复杂。你不得不在这个函数里面调用更多的函数来分离各个功能。
那么,新的这些函数应该如何管理?
而当我使用一个含有 write
方法的类,并配合 print
函数的 file
关键字来实现这个功能的时候,我可以通过这个类把相关的功能全部整合起来,封装成一个专门的模块,从而隐藏调用的细节。对外暴露的只有这个print_and_write对象的实例,而不需要额外写出它的任何方法。
而在代码的调用层,能够看到的就是带有 file
关键字的 print
函数,这样代码会显得非常简洁。