笨方法学Python(16-20)

习题16、读写文件

#!/usr/bin/python # -*- coding:utf-8 -*-from sys import argvscript, filename = argvprint "We're going to erase %r." % filename print "If you don't want that, hit CTRL-C (^C)." print "If you do want that, hit RETURN."raw_input("?")print "Opening the file..." target = open(filename, 'w')print "Truncating the file. Goodbye!" target.truncate()print "Now I'm going to ask you for three lines."line1 = raw_input("line 1: ") line2 = raw_input("line 2: ") line3 = raw_input("line 3: ")print "I'm going to write these to the file"target.write(line1) target.write("\n") target.write(line2) target.write("\n") target.write(line3) target.write("\n")print "And finally, we close it" target.close()

小结
  1. 如果用了'w' 参数, truncate()是必须的吗?
    看看加分习题 5。
  2. 'w' 是什么意思?
    它只是一个特殊字符串,用来表示文件的访问模式。如果你用了 ‘w’ 那么你的文件就是写入
    (write)模式。除了'w'以外,我们还有 'r'表示读取(read), 'a' 表示追加(append)。
  3. 还有哪些修饰符可以用来控制文件访问?
    最重要的是+修饰符,写法就是 'w+','r+','a+' ——这样的话文件将以同时读写的方式打开,而对于文件位置的使用也有些不同。
  4. 【笨方法学Python(16-20)】如果只写 open(filename) 那就使用'r' 模式打开的吗?
    是的,这是open() 函数的默认工作方式。
    • close – 关闭文件。跟你编辑器的 文件->保存.. 一个意思。
    • read – 读取文件内容。你可以把结果赋给一个变量。
    • readline – 读取文本文件中的一行。
    • truncate – 清空文件,请小心使用该命令。
    • write(stuff) – 将stuff 写入文件。
习题17、更多文件操作
#!/usr/bin/python # -*- coding:utf-8 -*-from sys import argv from os.path import existsscript, from_file, to_file = argvprint "Copying from %s to %s" % (from_file, to_file)# We could do these two on one line too, how? in_file = open(from_file) indata = https://www.it610.com/article/in_file.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 continuee, CTRL-C to abort." raw_input()out_file = open(to_file, 'w') out_file.write(indata)print "Alright, all done."out_file.close() in_file.close()

小结
  1. len()函数的功能是什么?
    它会以数字的形式返回你传递的字符串的长度。试着玩玩吧。
  2. 当我把代码写短时,我在关闭文件时出现一个错误。
    很可能是你写了indata = https://www.it610.com/article/open(from_file).read() 这意味着你无需再运行
    in_file.close() 了,因为 read()一旦运行, 文件就会被读到结尾并且被 close 掉。
习题18、命名、变量、代码、函数
#!/usr/bin/python # -*- coding:utf-8 -*-# this one s like your scripts with argv def print_two(*args): arg1, arg2 = args print "arg1: %r, arg2: %r " % (arg1, arg2)# ok, that *args is actually pointless, we can just do this def print_two_again(arg1, arg2): print "arg1: %r, arg2: %r " % (arg1, arg2)# this just takes one argument def print_one(arg1): print "arg1: %r " % arg1# this one takes no arguments def print_none(): print "I got nothing."print_two("Zed", "Shaw") print_two_again("Zed", "Shaw") print_one("First!") print_none()

小结
  1. 函数名称有什么规则?
    和变量名一样,只要以字母数字以及下划线组成,而且不是数字开始,就可以了。
  2. *args*是什么意思?
    它的功能是告诉 python 让它把函数的所有参数都接受进来,然后放到名字叫args的列表中去。和你一直在用的argv差不多,只不过前者是用在函数上面。没什么特殊情况,我们一般不会经常用到这个东西。
习题19、函数和变量
#!/usr/bin/python # -*- coding:utf-8 -*-def cheese_and_crackers(cheese_count, boxes_of_crackers): print "You have %d cheeses!" % cheese_count print "You have %d boxes of crackers!" % boxes_of_crackers print "Man that's engouh for a party!" print "Get a blanket.\n"print "We can just give the function numbers directly:" cheese_and_crackers(20, 30)print "OR, we can use variables from our script:" amount_of_cheese = 10 amount_of_crackers = 50cheese_and_crackers(amount_of_cheese, amount_of_crackers)print "We can even do math inside too:" cheese_and_crackers(10 + 20, 5 + 6)print "And we can combine the two, variables and math:" cheese_and_crackers(amount_of_cheese + 100, amount_of_crackers + 1000)

小结
  1. 怎样处理用户输入的数字,例如我想让用户输入克力架和奶酪的数量?
    记住使用int()raw_input()的值转为整数。
  2. 第 13 和 14 行创建的变量会不会改变函数中的变量?
    不会。这些变量是在函数之外的,当它们被传递到函数中以后,函数会为这些变量创建一些临时的
    版本,当函数运行结束后,这些临时变量就被丢弃了,一切又回到了从前。继续阅读本书,后面你
    会更清楚这些概念。
  3. 把全局变量(如 13、14 行)的名称和函数变量的名称取成一样的,这样做是不是不好?
    是的,因为这样的话你就无法确定哪个是哪个了。有时候你可能会必须使用同一个变量名,有时候
    你会不小心使用了一样的变量名,不论如何,只要有可能,还是尽量避免变量名称相同吧。
  4. 第 12-19 行是不是覆写了函数 cheese_and_crackers?
    没有,完全没有。这只是函数调用而已。基本上就是这里会跳转到函数的第一行,然后等函数运行
    完后再回到先前的位置。并没有把原函数怎么地。
  5. 函数的参数个数有限制吗?
    取决于 Python 的版本和你的操作系统,不过就算有限,限值也是很大的。实际应用中,5 个参数
    就不少了,再多就会让人头疼了。
  6. 可以在函数中调用函数吗?
    可以。后面的习题中你会用这一技巧写一个游戏。
习题20、函数和文件
#!/usr/bin/python # -*- coding:utf-8 -*-from sys import argvscript, input_file = argvdef print_all(f): print f.read()def rewind(f): f.seek(0)def print_a_line(line_count, f): print line_count, f.readline()current_file = open(input_file)print "First let's print the whole file:\n"print_all(current_file)print "Now let's rewind, kind of like a tape."rewind(current_file)print "Let's print three lines:"current_line = 1 print_a_line(current_line, current_file)current_line = current_line + 1 print_a_line(current_line, current_file)current_line = current_line + 1 print_a_line(current_line, current_file)

小结
  1. print_all 和其它函数里的f是什么?
    和 ex18 里的一样,f只是一个变量名而已,不过在这里它指的是一个文件。Python 里的文件就和老式磁带机,或者 DVD 播放机差不多。它有一个用来读取数据的“磁头”,你可以通过这个“磁头”来操作文件。每次你运行 f.seek(0) 你就回到了文件的开始,而运行f.readline()则会读取文件的一行,然后将“磁头”移动到 \n后面。后面你会看到更详细的解释。
  2. 问什么文件里会有间隔空行?
    readline()函数返回的内容中包含文件本来就有的 \n,而 print 在打印时又会添加一个\n,这样一来就会多出一个空行了。解决方法是在 print语句结尾加一个逗号,,这样 print 就不会把它自己的 \n打印出来了。
  3. 为什么seek(0) 没有把 current_line 设为 0?
    首先 seek()函数的处理对象是 字节 而非行,所以seek(0)只是转到文件的 0 byte,也就是第一个 byte 的位置。其次,current_line只是一个独立变量,和文件本身没有任何关系,我们只能手动为其增值。
  4. +=是什么?
    英语里边 “it is” 可以写成 “it’s”,”you are” 可以写成 “you’re”,这叫做简写。而这个操作符是把 =+简写到一起了。x += y的意思和x = x + y是一样的。
  5. readline()是怎么知道每一行在哪里的?
    readline()里边的代码会扫描文件的每一个字节,直到找到一个\n为止,然后它停止读取文件,并且返回此前的文件内容。文件 f 会记录每次调用readline()后的读取位置,这样它就可以在下次被调用时读取接下来的一行了。

    推荐阅读