题目
通过前学习的文件操作把一个文件中的内容拷贝到另一个文件中,并使用 os.path.exists
在拷贝前判断被拷贝的文件是否已经存在,之后由用户判断是否继续完成拷贝。
新知识
os.path.exists
是一个本题的新知识点。和 sys
一样,os
也是 python 自带的基本库中的一员,主要提供和操作系统有关的功能。其中 path
正如其名提供了和路径操作有关的功能。在 path
模块中拥有 exists
这个方法,它的作用是判断所提供的文件名是否已经存在于磁盘中,如果已经存在则返回 False
,反之则返回 True
len()
用来返回其中项目的数量,例如
# 返回字符串的长度
>>> len("hahaha")
6
加分练习
- 在多读读
import
的资料,将 python 运行起来,试试这条命令。 - 这个脚本是在有点烦人,没必要在拷贝前问一遍把,没必要在屏幕上打印那么多东西吧。试着删掉一部分功能,让它使用起来更加友好。
- 看看你能把这个脚本改多短,Zed 能改为一行。
- 在 liunx 系统的同学可以了解一下
cat
命令(shell终端中输入man cat
),通过它检查拷贝是否成功了。 - 找出为什么要在代码中写
out_put.close()
我的答案
17.0 基础练习
# 引入库
from sys import argv
from os.path import exists
# 解包参数
script, from_file, to_file = argv
# 打印任务目标
print("Copying from %s to %s" % (from_file, to_file))
# we could do these two on one line too, how?
# 如何把这两行写到一行?
in_put = open(from_file)
indata = in_put.read()
# 打印文件字符长度。
print("The input file is %d bytes long" % len(indata))
# 打印目标文件是否已经存在。
print("Does the output file exist? %r" % exists(to_file))
# 用户决定是否完成复制操作
print("Ready, hit RETURN to continue, CTRL-C to abort.")
input()
# 以写入模式打开目标文件
out_put = open(to_file, 'w')
# 写入复制的内容
out_put.write(indata)
# 打印操作完成(实际打印这段话的时候根本没完成)
print("Alright, all done.")
# 关闭文件(真保存至硬盘)
out_put.close()
in_put.close()
利用了之前练习产生的 test.txt
进行拷贝。linux下的同学使用 cat copied.txt
可以把拷贝后的内容打印在屏幕上
17.2 友好的精简代码
from sys import argv
script, from_file, to_file = argv
# 一行读取源文件
indata = open(from_file).read()
# 一行写入
open(to_file, 'w').write(indata)
# 要友好么?就在完成的时候打印一句话吧
print("拷贝完成,共复制 %d 个字" % len(indata))
这样一来,只是读取和写入文件,其他提示都没有,如果文件已存在则直接覆盖。实际代码缩减到了 5 行,删掉 print 的话只有 4 行。
17.3 极限精简
from sys import argv
script, from_file, to_file = argv
open(to_file, 'w').write(open(from_file).read())
大神和菜鸟的区别就是大神一行,菜鸟几行…
这是我目前能做到的极限了,不知道 Zed 怎么能把 import 解包 代码写到一行里面。
17.5 为什么要 output.close()
原因在于如果不写,则新复制的文件中是不会保存任何内容的。也就是没有保存(如同在 16 题 Zed 介绍的一样)
out_put = open(to_file, 'w')
执行时会创建 to_file 文件,但是没内容
out_put.write(indata)
执行时,内容会写入到 to_file 的内存数据中,但仍未写入硬盘。
只有在执行 close 时 python 才指定文本的各种操作已经结束了,不会再有任何变化,这个时候在写入硬盘可以尽可能地减少硬盘读写操作,提高效率(特别在特大文件的时候)
那么为什么在 精简练习、极限精简练习 中不需要关闭呢?
我的理解:
关键点在于没有使用变量,也就是没有个打开的文件起名字。
这个时候,任何操作是一次性的,我们没办法在写入了一些东西后再说“喂,就你,你再写入这些内容”,python 不知道这句‘喂’说的是哪一个内存堆栈中的数据。
所有没有其名的代码都是一次性的,不会保存在内存中,针对 open 来说,python 就自动关闭它了。