这是前段时间我们公司招聘笔试的一道比较简单的题。它面向初级和中级程序员,但很少有人能完全回答。题本身不难,主要是考察动手能力和基本的代码功底。如果您要找工作,请将其保存以备后用。看题:请指出以下代码段中的错误>>>f=open("test.txt",mode="w")>>>f.write(u"PythonZen")解析:Python提供内部函数open,用于读写文件。函数返回一个文件对象,可以用来读写文件,由参数mode控制。默认是读取文件>>>f=open("test.txt")>>>f.read()python之禅上面代码在python2中运行会报错:Traceback(mostrecentcallast):File"",line1,inUnicodeEncodeError:'ascii'codeccan'tencodecharactersinposition6-7:ordinalnotinrange(128)这是字符编码问题。编码错误是Python程序员遇到的最常见的错误。reason之前在公众号写过编码错误。报错的原因是程序不能直接保存unicode字符串,必须先转换成str类型的二进制字节序列才能保存。write方法会自动为你做编码转换。默认使用ascii编码格式。因为ascii字符集不能处理中文,所以会出现UnicodeEncodeError错误。正确的做法是在调用write之前手动转换为utf-8或gbk编码的str类型。>>>f=open("test.txt",mode="w")>>>content=u"Python之禅">>>contentcontent=content.encode(encoding='utf-8')>>>f.write(content)第二个问题是文件对象没有正常关闭。可能有人会问,不关闭文件会有什么影响呢?可以打开的文件描述符的数量是有限的。比如linux是65536,那么这个文件一定要关闭。>>>f=open("test.txt",mode="w")>>>content=u"Python之禅">>>contentcontent=content.encode(encoding='utf-8')>>>f.write(content)>>>f.close()close一切都会好起来吗?不必要。因为在调用open函数的时候有可能会报错,比如因为权限问题导致无法读写目录下的文件。这时候文件对象还没有创建成功,调用close肯定会报错。再比如第4行写的时候可能会报错,因为磁盘空间不足,此时如果报错,close方法就没有机会执行了。正确的方法是使用tryexcept来捕获异常。注意open函数应该在try代码块之外f=open("output.txt","w")try:content=u"PythonZen"f.write(content.encode(encoding='utf-8'))exceptIOErrorase:print("oops,%s"%e.args[0])finally:f.close()然而,更优雅的写法是用...as,因为文件对象实现了上下文管理器protocol,当程序进入with语句块时,文件对象会被赋值给变量f,程序退出with语句块时会自动调用close方法。withopen("output.txt","w")asf:content=u"ZenofPython"f.write(content.encode(encoding='utf-8'))***另一个问题是兼容性,open函数python2和python3不同,后者可以在函数中指定字符编码格式,而python2没有。#python3withopen("output.txt","w",encoding="utf-8")asf:content=u"ZenofPython"f.write(content)那么如何写一个兼容两者的open函数2和3?是的,使用io模块下的open函数。python2中的io.open相当于python3中的open函数。您可以指定编码参数。同时python3还保留了io.open函数fromioimportopenwithopen("output.txt","w",encoding='utf-8')asf:f.write(u"Python之禅")【本文为专栏作者“刘志军”的原创文章,作者微信公众号:Python之禅(VTtalk)】戳这里,阅读更多本作者的好文
