|
2 | 2 |
|
3 | 3 | #文件(1) |
4 | 4 |
|
5 | | -文件,是computer姑娘中非常重要的东西,在python里,它也是一种类型的对象,类似前面已经学习过的其它数据类型,包括文本的、图片的、音频的、视频的等等,还有不少没见过的扩展名的。事实上,在linux操作系统中,所有的东西都被保存到文件中。 |
| 5 | +文件,是computer姑娘中非常重要的东西。如在Linux操作系统中,所有的东西都被保存到文件中。 |
6 | 6 |
|
7 | | -先在交互模式下查看一下文件都有哪些属性: |
| 7 | +在Python里,它也很重要。只不过,Python 2和Python 3对它的态度有点不同。 |
| 8 | + |
| 9 | +在Python 2中,文件也是一种内建类型对象,其地位等同于前面已经学习过的列表、整数、字符串等类型。 |
| 10 | + |
| 11 | +在交互模式下,我们可以用`dir()`这种已经熟练的方法查看相关属性和方法。 |
8 | 12 |
|
9 | 13 | >>> dir(file) |
10 | 14 | ['__class__', '__delattr__', '__doc__', '__enter__', '__exit__', '__format__', '__getattribute__', '__hash__', '__init__', '__iter__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'close', 'closed', 'encoding', 'errors', 'fileno', 'flush', 'isatty', 'mode', 'name', 'newlines', 'next', 'read', 'readinto', 'readline', 'readlines', 'seek', 'softspace', 'tell', 'truncate', 'write', 'writelines', 'xreadlines'] |
11 | 15 |
|
12 | | -然后对部分属性进行详细说明,就是看官学习了。 |
| 16 | +然而,这一切在Python 3中都变了。在Python 3中,再没有`file`这个内建类型了。如果读者使用的是Python 3,执行`dir(file)`,会报错,并且显示`NameError: name 'file' is not defined`。 |
13 | 17 |
|
14 | | -特别注意观察,在上面有`__iter__`这个东西。曾经在讲述列表的时候,是不是也出现这个东西了呢?是的。它意味着这种类型的数据是可迭代的(iterable)。在下面的讲解中,你就会看到了,能够用for来读取其中的内容。 |
| 18 | +但,这并不妨碍我们对文件的研究。 |
| 19 | + |
| 20 | +暂且观察Python 2的`dir(file)`结果,里面有`__iter__`这个东西。曾经在讲述列表的时候,是不是也出现这个东西了呢?是的。它意味着这种类型的对象是可迭代的(iterable)。在下面的讲解中,你就会看到了,能够用for来读取其中的内容。 |
15 | 21 |
|
16 | | -##打开文件 |
| 22 | +##读文件 |
17 | 23 |
|
18 | 24 | 在某个文件夹下面建立了一个文件,名曰:130.txt,并且在里面输入了如下内容: |
19 | 25 |
|
|
27 | 33 |
|
28 | 34 |  |
29 | 35 |
|
30 | | -在上面截图中,我在当前位置输入了python(我已经设置了环境变量,如果你没有,需要写全启动python命令路径),进入到交互模式。在这个交互模式下,这样操作: |
| 36 | +在上面截图中,我在当前位置输入了`python`,进入到交互模式。在这个交互模式下,这样操作: |
31 | 37 |
|
32 | 38 | >>> f = open("130.txt") #打开已经存在的文件 |
33 | 39 | >>> for line in f: |
34 | | - ... print line |
| 40 | + ... print line #Python 3: print(line) |
35 | 41 | ... |
36 | 42 | learn python |
37 | 43 |
|
38 | 44 | http://qiwsir.github.io |
39 | 45 |
|
40 | 46 | qiwsir@gmail.com |
41 | 47 |
|
42 | | -提醒初学者注意,在那个文件夹输入了启动python交互模式的命令,那么,如果按照上面的方法`open("130.txt")`打开文件,就意味着这个文件130.txt是在当前文件夹内的。如果要打开其它文件夹内的文件,请用相对路径或者绝对路径来表示,从而让python能够找到那个文件。 |
| 48 | +提醒初学者注意,在那个目录里输入了启动Python交互模式的命令,那么,如果按照上面的方法`open("130.txt")`打开文件,就意味着这个文件130.txt是在当前文件夹内的。如果要打开其它文件夹内的文件,请用相对路径或者绝对路径来表示,从而让Python能够找到那个文件。 |
43 | 49 |
|
44 | | -将打开的文件,赋值给变量f,这样也就是变量f跟对象文件130.txt用线连起来了(对象引用),本质上跟前面所讲述的其它类型数据进行赋值是一样的。 |
| 50 | +将打开的文件,赋值给变量`f`,这样也就是变量`f`跟对象文件130.txt用线连起来了(对象引用),本质上跟前面所讲述的其它对象进行赋值是一样的。 |
45 | 51 |
|
46 | | -接下来,用for来读取文件中的内容,就如同读取一个前面已经学过的序列对象一样,如list、str、tuple,把读到的文件中的每行,赋值给变量line。也可以理解为,for循环是一行一行地读取文件内容。每次扫描一行,遇到行结束符号\n表示本行结束,然后是下一行。 |
| 52 | +接下来,用`for`来读取文件中的内容,就如同读取一个前面已经学过的序列对象一样,把读到的文件中的每行,赋值给变量`line`。也可以理解为,用`for`循环一行一行地读取文件内容。每次扫描一行,遇到行结束符号`\n`表示本行结束,然后是下一行。 |
47 | 53 |
|
48 | 54 | 从打印的结果看出,每一行跟前面看到的文件内容中的每一行是一样的。只是行与行之间多了一空行,前面显示文章内容的时候,没有这个空行。或许这无关紧要,但是,还要深究一下,才能豁然。 |
49 | 55 |
|
50 | | -在原文中,每行结束有本行结束符号\n,表示换行。在for语句汇总,print line表示每次打印完line的对象之后,就换行,也就是打印完line的对象之后会增加一个\n。这样看来,在每行末尾就有两个\n,即:\n\n,于是在打印中就出现了一个空行。 |
| 56 | +在原文中,每行结束有本行结束符号`\n`,表示换行。`print line`或者`print(line)`默认情况下,打印完`line`的对象之后会增加一个`\n`。这样看来,在每行末尾就有两个`\n`,即:`\n\n`,于是在打印中就出现了一个空行。 |
51 | 57 |
|
52 | 58 | >>> f = open('130.txt') |
53 | 59 | >>> for line in f: |
54 | | - ... print line, #后面加一个逗号,就去掉了原来默认增加的\n了,看看,少了空行。 |
| 60 | + ... print line, #Python 3: print(line, end=',') |
55 | 61 | ... |
56 | 62 | learn python |
57 | 63 | http://qiwsir.github.io |
58 | 64 | qiwsir@gmail.com |
59 | 65 |
|
60 | | -在进行上述操作的时候,有没有遇到这样的情况呢? |
61 | | - |
62 | | - >>> f = open('130.txt') |
63 | | - >>> for line in f: |
64 | | - ... print line, |
65 | | - ... |
66 | | - learn python |
67 | | - http://qiwsir.github.io |
68 | | - qiwsir@gmail.com |
| 66 | +如果读者完成了上述操作,紧接着做下面的操作: |
69 | 67 |
|
70 | 68 | >>> for line2 in f: #在前面通过for循环读取了文件内容之后,再次读取, |
71 | | - ... print line2 #然后打印,结果就什么也显示,这是什么问题? |
| 69 | + ... print line2 #然后打印,结果就什么也显示,这是什么问题? |
72 | 70 | ... |
73 | 71 | >>> |
74 | 72 |
|
75 | | -如果看官没有遇到上面问题,可以试试。这不是什么错误,是因为前一次已经读取了文件内容,并且到了文件的末尾了。再重复操作,就是从末尾开始继续读了。当然显示不了什么东西,但是python并不认为这是错误,因为后面就会讲到,或许在这次读取之前,已经又向文件中追加内容了。那么,如果要再次读取怎么办?就重新来一遍好了。这就好比有一个指针在指着文件中的每一行,每读完一行,指针向下移动一行,直到指针指向了文件的最末尾。当然,也有办法把指针移动到任何位置。 |
| 73 | +这不是什么错误,是因为前一次已经读取了文件内容,并且到了文件的末尾了。再重复操作,就是从末尾开始继续读了。当然显示不了什么东西,但是Python并不认为这是错误。后面会对此进行讲解。 |
76 | 74 |
|
77 | | -特别提醒看官,因为当前的交互模式是在该文件所在目录启动的,所以,就相当于这个实验室和文件130.txt是同一个目录,这时候我们打开文件130.txt,就认为是在本目录中打开,如果文件不是在本目录中,需要写清楚路径。 |
| 75 | +在这里,如果要再次读取,那就从新`f = open('130.txt')`。有点麻烦!怎奈知识尚不充足。 |
78 | 76 |
|
79 | | -比如:在上一级目录中(~/Documents/ITArticles/BasicPython),假如我进入到那个目录中,运行交互模式,然后试图打开130.txt文件。 |
| 77 | +使用Python 3的读者,这里要注意了,如果你已经执行了`f = open('130.txt')`,就是已经建立了一个文件对象,这时候可以使用`dir()`来查看这个对象的方法和属性了。 |
| 78 | + |
| 79 | + >>> f = open("130.txt") |
| 80 | + >>> dir(f) |
| 81 | + ['_CHUNK_SIZE', '__class__', '__del__', '__delattr__', '__dict__', '__dir__', '__doc__', '__enter__', '__eq__', '__exit__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__lt__', '__ne__', '__new__', '__next__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_checkClosed', '_checkReadable', '_checkSeekable', '_checkWritable', '_finalizing', 'buffer', 'close', 'closed', 'detach', 'encoding', 'errors', 'fileno', 'flush', 'isatty', 'line_buffering', 'mode', 'name', 'newlines', 'read', 'readable', 'readline', 'readlines', 'seek', 'seekable', 'tell', 'truncate', 'writable', 'write', 'writelines'] |
| 82 | + |
| 83 | +不管两个版本的显示结果有哪些不同,它们相同的是都有`__iter__`属性,意味着在两个版本中,文件对象都是可迭代的。 |
| 84 | + |
| 85 | +特别提醒,因为我所演示的交互模式是在该文件所在目录启动的,所以,就相当于这个实验室和文件130.txt是同一个目录,这时候我们打开文件130.txt,就认为是在本目录中打开,如果文件不是在本目录中,需要写清楚路径。 |
| 86 | + |
| 87 | +比如:在上一级目录中(`~/Documents/ITArticles/BasicPython`),假如我进入到那个目录中,运行交互模式,然后试图打开130.txt文件。 |
80 | 88 |
|
81 | 89 |  |
82 | 90 |
|
|
85 | 93 | File "<stdin>", line 1, in <module> |
86 | 94 | IOError: [Errno 2] No such file or directory: '130.txt' |
87 | 95 |
|
88 | | - >>> f = open("./codes/130.txt") #必须得写上路径了(注意,windows的路径是\隔开,需要转义。对转义符,看官看以前讲座) |
| 96 | + >>> f = open("./codes/130.txt") #必须得写上路径了(注意,windows的路径分隔符与此不同。) |
89 | 97 | >>> for line in f: |
90 | 98 | ... print line |
91 | 99 | ... |
|
95 | 103 |
|
96 | 104 | qiwsir@gmail.com |
97 | 105 |
|
98 | | - >>> |
| 106 | +读文件,只是针对文件的操作之一,还有创建文件。 |
99 | 107 |
|
100 | 108 | ##创建文件 |
101 | 109 |
|
102 | 110 | 上面的实验中,打开的是一个已经存在的文件。如何创建文件呢? |
103 | 111 |
|
104 | | - >>> nf = open("131.txt","w") |
| 112 | + >>> nf = open("131.txt", "w") |
105 | 113 | >>> nf.write("This is a file") |
106 | 114 |
|
107 | 115 | 就这样创建了一个文件?并写入了文件内容呢?看看再说: |
|
110 | 118 |
|
111 | 119 | 真的就这样创建了新文件,并且里面有那句话呢。 |
112 | 120 |
|
113 | | -看官注意了没有,这次我们同样是用open()这个函数,但是多了个"w",这是在告诉python用什么样的模式打开文件。也就是说,用open()打开文件,可以有不同的模式打开。看下表: |
| 121 | +创建文件,我们同样是用`open()`这个函数,但是多了个`"w"`,这是在告诉Python用什么样的模式打开文件。也就是说,用`open()`操作文件,可以有不同的模式。看下表: |
114 | 122 |
|
115 | 123 | | 模式 | 描述 | |
116 | 124 | |------|------| |
|
130 | 138 | >>> f = open("130.txt","r") |
131 | 139 | >>> f |
132 | 140 | <open file '130.txt', mode 'r' at 0xb750a700> |
| 141 | + |
| 142 | +Python 3中显示的结果信息更丰富、明确。 |
| 143 | + |
| 144 | + >>> f |
| 145 | + <_io.TextIOWrapper name='130.txt' mode='r' encoding='cp936'> |
133 | 146 |
|
134 | | -可以用这种方式查看当前打开的文件是采用什么模式的,上面显示,两种模式是一样的效果,如果不写那个"r",就默认为是只读模式了。下面逐个对各种模式进行解释 |
| 147 | +可以用这种方式查看当前打开的文件是采用什么模式的,上面显示,两种模式是一样的效果,如果不写那个`"r"`,就默认为是只读模式了。下面逐个对各种模式进行解释 |
135 | 148 |
|
136 | 149 | **"w":以写方式打开文件,可向文件写入信息。如文件存在,则清空该文件,再写入新内容** |
137 | 150 |
|
138 | 151 | 131.txt这个文件是存在的,前面建立的,并且在里面写了一句话:This is a file |
139 | 152 |
|
140 | 153 | >>> fp = open("131.txt") |
141 | 154 | >>> for line in fp: #原来这个文件里面的内容 |
142 | | - ... print line |
| 155 | + ... print line #Python 3: print(line) |
143 | 156 | ... |
144 | 157 | This is a file |
145 | 158 | >>> fp = open("131.txt","w") #这时候再看看这个文件,里面还有什么呢?是不是空了呢? |
|
187 | 200 | This is about 'with...as...' |
188 | 201 | >>> |
189 | 202 |
|
190 | | -这里就不用close()了。而且这种方法更有python味道,或者说是更符合Pythonic的一个要求。 |
| 203 | +这里就不用close()了。而且这种方法更有Python味道,或者说是更符合Pythonic的一个要求。 |
191 | 204 |
|
192 | 205 | ------ |
193 | 206 |
|
|
0 commit comments