1.IO参数
r 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。
rb 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。
r+ 打开一个文件用于读写。文件指针将会放在文件的开头。
rb+ 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。
w 打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
wb 以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
w+ 打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
wb+ 以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
a 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
ab 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
a+ 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。
2.IO
#P1 打开文件、读文件、关闭文件的典型方法
try:
f=open('D:/test.txt','r')
print(f.read())
finally:
if f:
f.close()
#P2 推荐的简洁写法,不必显示的关闭文件描述符
#open返回的对象在python中称作file-like 对象,可以是字节流、网络流、自定义流等
with open('D:/test.txt','r') as f:
#按行读取
for line in f.readlines():
print(line.strip())
#P3 直接读取二级制的图片、视频文件
with open(‘D:/banner.jpg’,’rb’) as f2:
for line in f2.readlines():
print(line.strip())
#P4 可以指定编码读取相应的数据,还可以忽略非法编码
with open('D:/test.txt','r',encoding='gbk',errors='ignore') as f3:
for line in f3.readlines():
print(line.strip())
#P5 写文件的流程和读文件是一样的 代开文件、写入内容、关闭文件
# ‘r’ open for reading (default)
# ‘w’ open for writing, truncating the file first
# ‘x’ open for exclusive creation, failing if the file already exists
# ‘a’ open for writing, appending to the end of the file if it exists
# ‘b’ binary mode
# ‘t’ text mode (default)
# ‘+’ open a disk file for updating (reading and writing)
# ‘U’ universal newlines mode (deprecated)*
with open('D:/test12.txt','a+') as f4:
for line in f4.readlines():
print(line.strip())
f4.write('a new line2!')
ab+ 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。
3.
python的一种赋值
a,b=b,a+b
可以拆成
a = b, b = a + b
也就是说等号左边的第一个位置的等于等号右边的第一个位置
等号左边第二个位置的等于等号右边第二个位置的。
(a, b) = (b, a + b)
要这样看才行
4.协程
yield
解释器在遇到这个语句时,先计算expression,然后将结果返回给上一个调用者。而在第二次调用next()时,会从yield的下个语句开始执行。而不是你所理解的。
而讲到send()和next()的区别:
1 def consumer():
2 r = 'here'
3 for i in xrange(3):
4 yield r
5 r = '200 OK'+ str(i)
6
7 c = consumer()
8 n1 = c.next ()
9 n2 = c.next ()
10 n3 = c.next ()
对于普通的生成器,第一个next 调用,相当于启动生成器,会从生成器的第一行代码开始执行,直到第一次执行完yield语句(第4行),然后跳出生成器函数。
然后第二个next 调用,从yield语句的下一句语句执行(第5行),然后重新运行到yield语句,执行后跳出,后面的以此类推。
1 def consumer():
2 r = 'here'
3 while True:
4 n1 = yield r
5 if not n1:
6 return
7 print('[CONSUMER] Consuming %s...' % n1)
8 r = '200 OK'+str(n1)
9
10 def produce(c):
11 aa = c.send(None)
12 n = 0
13 while n < 5:
14 n = n + 1
15 print('[PRODUCER] Producing %s...' % n)
16 r1 = c.send(n)
17 print('[PRODUCER] Consumer return: %s' % r1)
18 c.close()
19
20 c = consumer()
21 produce(c)
send(msg)和next ()在一定程度上是类似的,区别是send()可以传递yield表达式的值进去,而next ()不能,只能传递None进去。我们可以看做next ()和send(None)是一致的
注意:第一次调用时,使用next ()或send(None),不能使用send发送一个非None的值,否则会报错,因为没有python yield语句来接收这个值。
第一次执行send(None)(11行),启动生成器,第一行代码执行到yield后,跳出生成器函数,此时,n1一直没有定义。
下面运行到c.send(1),进入生成器函数,从第4行开始执行,先把1赋值给n1,但是并不执行yield语句部分。
下面继续从yield的下一语句继续执行,然后重新运行到yield语句,执行后,跳出生成器。
综上,send和next 相比,多了一次赋值的动作,其他的流程是相同的。