练习 17. 更多文件

现在让我们对文件做更多新的操作。我们会写一个 Python 脚本来把一个文件复制成另一个。代码会非常短,但是能让你学会对文件做更多的操作。

ex17.py

    1. 1 from sys import argv
    2. 2 from os.path import exists
    3. 3
    4. 4 script, from_file, to_file = argv
    5. 5
    6. 6 print(f"Copying from {from_file} to {to_file}")
    7. 7
    8. 8 # we could do these two on one line, how?
    9. 9 in_file = open(from_file)
    10. 10 indata = in_file.read()
    11. 11
    12. 12 print(f"The input file is {len(indata)} bytes long")
    13. 13
    14. 14 print(f"Does the output file exist? {exists(to_file)}")
    15. 15 print("Ready, hit RETURN to continue, CTRL-C to abort.")
    16. 16 input()
    17. 17
    18. 18 out_file = open(to_file, 'w')
    19. 19 out_file.write(indata)
    20. 20
    21. 21 print("Alright, all done.")
    22. 22
    23. 23 out_file.close()
    24. 24 in_file.close()

你应该会很快注意到我们输出了另一个常用命令 exists。它会基于一个字符串里面的变量文件名来判断,如果一个文件存在,它就会返回 True,不存在就会返回 False。我们会在这本书的下半部分经常使用这个函数,现在你只用知道你是如何输出它的。

使用 import 可以调出海量的免费代码,这些是程序员已经写过的代码,你就不用重复造轮子了。

你会看到

像你其他的脚本文件一样运行 ex17.py ,再加上两个变量:一个是要复制的源文件,一个是要复制到的目标文件。我会使用一个叫 test.txt 的示例文件:

练习 17 会话 # first make a sample file echo "This is a test file." > test.txt # then look at it cat test.txt This is a test file. # now run our script on it python3.6 ex17.py test.txt new_file.txt Copying from test.txt to new_file.txt The input file is 21 bytes long Does the output file exist? False Ready, hit RETURN to continue, CTRL-C to abort. Alright, all done.

它应该对每一个文件都适用,多试一些看看会发生什么。注意不要动重要的文件。

警告!
你应该注意到我使用了 cat 命令来显示文件内容。如果你不懂,可以在附录 A 的命令行速成教程中学到这个命令。

附加练习

  • 这个脚本真的很烦人。在复制之前其实没必要问你,而且它打印了太多内容,试着通过删掉一些特征让这个脚本更简洁一些。
  • 看看你把这个脚本缩到多短,我可以把它变成一行。
  • 注意“你会看到”部分,我用了 cat,这是一种把文件打印到屏幕的简单办法,你可以输入 man cat 来看看关于这个命令的作用。
  • 弄明白你为什么得在代码里写 out_file.close()
  • 去读读 Python 的 import statement,然后自己试试 import 一些东西,看能不能成功运行。不成功也没关系。

常见问题

为什么 'w' 要用引号? 因为这是一个字符串。你已经用了一段时间字符串了,确保你知道它的含义。

你不可能把那些代码变成一行! 那;取决于;你;如何;定义;一行;代码。

我觉得这个练习很难,这正常吗? 是的,很正常。甚至到练习 36 的时候,或者学完这本书的时候,你可能还是会觉得很难。每个人的情况都不一样,所以坚持学下去,坚持做练习,要有耐心。

len() 函数是什么作用? 它能够取字符串的长度,然后返回一个数字。你可以试着玩玩。

但我试着把这些代码缩短的时候,我在关闭文件时遇到了错误。 你可能用了 indata = open(from_file).read(),这意味着你不需要在之后再输入 in_file.close() ,因为你已经到了脚本的最后。一旦那一行运行过之后,它就已经被 Python 关掉了。

我收到了一个这样的错误:Syntax:EOL while scanning string literal 你忘了在字符串后面加引号了,再检查一遍的代码。