习题 20: 函数和文件 ******************************** 回忆一下函数的要点,然后一边做这节练习,一边注意一下函数和文件是如何\ 在一起协作发挥作用的。 .. literalinclude:: ex/ex20.py :linenos: 特别注意一下,每次运行 ``print_a_line`` 时,我们是怎样传递当前的行号\ 信息的。 你应该看到的结果 =================== .. literalinclude:: ex/ex20.txt :language: console 加分习题 ============ 1. 通读脚本,在每行之前加上注解,以理解脚本里发生的事情。 2. 每次 ``print_a_line`` 运行时,你都传递了一个叫 ``current_line`` 的变量。\ 在每次调用函数时,打印出 ``current_line`` 的至,跟踪一下它在 ``print_a_line`` 中是怎样变成 ``line_count`` 的。 3. 找出脚本中每一个用到函数的地方。检查 ``def`` 一行,确认参数没有用错。 4. 上网研究一下 ``file`` 中的 ``seek`` 函数是做什么用的。试着运行 ``pydoc file`` 看看能不能学到更多。 5. 研究一下 ``+=`` 这个简写操作符的作用,写一个脚本,把这个操作符用在里边试一下。 常见问题回答 ========================== ``print_all`` 和其它函数里的 ``f`` 是什么? 和 Ex 18 里的一样, ``f`` 只是一个变量名而已,不过在这里它指的是一个文件。Python 里的\ 文件就和老式磁带机,或者 DVD 播放机差不多。它有一个用来读取数据的“磁头”,你可以通过这个\ “磁头”来操作文件。每次你运行 ``f.seek(0)`` 你就回到了文件的开始,而运行 ``f.readline()`` 则会读取文件的一行,然后将“磁头”移动到 ``\n`` 后面。后面你会看到更详细的解释。 问什么文件里会有间隔空行? ``readline()`` 函数返回的内容中包含文件本来就有的 ``\n``\,而 print 在打印时又会\ 添加一个 ``\n``\,这样一来就会多出一个空行了。解决方法是在 print 语句结尾加一个逗号 ``,``\,这样 print 就不会把它自己的 ``\n`` 打印出来了。 为什么 ``seek(0)`` 没有把 ``current_line`` 设为 0? 首先 ``seek()`` 函数的处理对象是 *字节* 而非行,所以 ``seek(0)`` 只是转到文件的 0 byte,也就是第一个 byte 的位置。其次, ``current_line`` 只是一个独立变量,和文件本身\ 没有任何关系,我们只能手动为其增值。 ``+=`` 是什么? 英语里边 "it is" 可以写成 "it's","you are" 可以写成 "you're",这叫做简写。而这个\ 操作符是吧 ``=`` 和 ``+`` 简写到一起了。 ``x += y`` 的意思和 ``x = x + y`` 是一样的。 ``readline()`` 是怎么知道每一行在哪里的? ``readline()`` 里边的代码会扫描文件的每一个字节,直到找到一个 ``\n`` 为止,然后它停止\ 读取文件,并且返回此前的文件内容。文件 ``f`` 会记录每次调用 ``readline()`` 后的读取\ 位置,这样它就可以在下次被调用时读取接下来的一行了。