社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

给Python新手的一道面试题:如何正确读写文件

Python之禅 • 7 年前 • 534 次点击  

这是我司前段时间招人笔试中一道比较简单题,面向初中级程序员,不过很少有人能回答完整的,问题本身不难,主要还是考察动手能力和基本代码功,准备找工作的先收藏留着以后用得着。

看题:请指出下面代码段中的错误

>>> f = open("test.txt", mode="w")
>>> f.write(u"python之禅")

分析:Python 提供了内建函数 open 用于读写文件,函数返回一个文件对象,可对文件进行读、写操作,用参数 mode 来控制。

参数说明
r读文件(默认)
w写文件  (如果文件中有内容,已有的内容将被覆盖)
a写文件(如果文件中有内容,新内容追后到文件后面)

默认是读文件

>>> f = open("test.txt")
>>> f.read()
python之禅

上面这段代码如果在python2中运行,会报错:

Traceback (most recent call last):
File ““, line 1, in
UnicodeEncodeError: ‘ascii’ codec can’t encode characters in position 6-7: ordinal not in range(128)

这是一个字符编码的问题,编码错误是Python程序员最经常遇到的错误,之前在公众号中写过关于编码错误的原因。

之所以报错是程序没法直接保存 unicode 字符串,要经过编码转换成而 str 类型的二进制字节序列才能够保存。

write 方法会自动帮你做编码转换,默认使用 ascii 编码格式,因为 ascii 字符集不能处理中文,所以出现了 UnicodeEncodeError 错误。

正确的方式是在调用 write 之前手动用 utf-8 或者 gbk 编码转换成 str 类型。

>>> f = open("test.txt", mode="w")
>>> content = u"Python之禅"
>>> content = content.encode(encoding='utf-8')
>>> f.write(content)

第二个问题是文件对象没有正常关闭,有人可能要问了,不关闭会有什么影响,操作完文件时,如果不关闭文件,那么将对系统造成资源浪费,因为系统可打开的文件描述符数量是有限制,比如 Linux 是 65536,所以必须要关闭文件。

>>> f = open("test.txt", mode="w")
>>> content = u"Python之禅"
>>> content = content.encode(encoding='utf-8')
>>> f.write(content)
>>> f.close()

close 就万事大吉了吗?未必。

因为有可能在调用 open 函数的时候就报错了,比如因为权限问题没法在该目录读写文件,此时,文件对象都没创建成功,调用close肯定会报错。

再比如在第4行 write 的时候有可能报错,因为磁盘空间不足,这个时候报错了, close 方法就没有机会执行了。

正确地做法是用 try except 对异常进行捕获。注意,open 函数要在 try 代码块外面

f = open("output.txt", "w")
try:
  content = u"Python之禅"
  f.write(content.encode(encoding='utf-8'))
except IOError as e:
   print("oops, %s" % e.args[0])
finally:
   f.close()

不过,更优雅的写法是用 with ... as 写法,因为 文件对象实现了上下文管理器协议,程序进入 with 语句块时,会把文件对象赋值给变量 f,在程序退出 with 语句块的时候会地自动调用 close 方法。

with open("output.txt", "w") as f:
    content = u"Python之禅"
   f.write(content.encode(encoding='utf-8'))

最后还有一个问题是兼容性,python2 与python3 的 open 函数不一样,后者可以在函数中指定字符编码格式,而 python2 则没有。

# python3

with open("output.txt", "w", encoding="utf-8") as f:
    content = u"Python之禅"
   f.write(content)

那么如何写出同时兼容2和3的open函数呢?

没错,使用 io 模块下的 open 函数,python2 中的 io.open 等价于 python3 中的 open 函数,可以指定 encoding 参数,同时 python3 也保留有 io.open 函数

from  io import open
with open("output.txt", "w", encoding='utf-8') as f:
   f.write(u"python之禅")

总结:

读写文件时,应该考虑的问题包括:字符编码问题,操作完文件要即时关闭文件描述符,同时还要注意代码的兼容性。

关注『Python之禅』,写好代码

近期推荐阅读:

PS:你们对代码的高亮效果还满意吗?你最喜欢的样式是?


今天看啥 - 高品质阅读平台
本文地址:http://www.jintiankansha.me/t/FECRaFDwHK
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/3320
 
534 次点击