一. 基本概念
-
同步和异步
同步:CPU 等待 IO 的执行结果
异步:CPU 不等待 IO 的执行结果
即:同步和异步的区别就是是否等待 IO 执行的结果 -
回调模式
打个比方:汉堡做好后,服务员跑来告诉你,这就是回调 -
轮询模式
汉堡做好后,服务员会了短信告诉你,而你需要不停的检查手机,这就是轮询
二. 文件的读写
- 以只读的方式打开文件
# 如果文件不存在,open() 函数就会抛出一个 IOError 异常
f = open("d:/TestData/test.txt", "r")
# 如果文件打开成功,返回一个文件对象,此对象可以调用 read() 方法可以一次读取文件的全部内容,返回一个str对象
content = f.read()
# 关闭文件对象,用以释放系统资源,因为操作系统同一时间能打开的文件数量是有限的
f.close()
- 无论是否读错都正确关闭文件
try:
f = open("e:/TestData/test.txt", "r")
print(f.read())
finally:
if f:
f.close()
- 用更简单的方式打开文件(
with...open
)
# 该方式会自动调用 close() 方法
with open("d:/TestData/test.txt", "r") as f_obj:
print(f_obj.read())
- 说明:调用
read()
方法时会一次读取文件的全部内容,如果文件太大,会爆内存
保险起见,可以按如下方式避免上述风险:
1)调用read(size)
方法,每次读取 size 个字节的内容
2)调用readline()
可以每次读取一行内容
3)调用readlines()
一次读取所有内容,并按行返回 list
with open("e:/TestData/test.txt", "r", encoding = "utf-8") as f_obj:
lines = f_obj.readlines()
for line in lines:
print(line.strip())
- 读二进制文件
f = open("d:/TestData/test.txt", "rb")
print(r.read())
f.close()
- 字符编码
# 要读取非 UTF-8 编码的文件,需要给 open() 函数传入 encoding 参数
f = open("d:/TestData/test.txt", "r", encoding = "gbk")
print(f.read())
f.close()
# 遇到编码不规范的文件,可能会报 UnicodeDecodeError 异常,
# 出现这种情况的原因可能是文件中夹杂了一些非法的编码字符,
# 可以使用 error 参数,表示遇到验证码错误后如何处理,下面的操作是直接忽略
f = open("d:/TestData/test.txt", "r", encoding = "utf-8", error = "ignore")
print(f.read())
f.close()
- 写文件
Note: 当我们写文件时,操作系统往往不会立刻把数据写入磁盘,而是放到内存缓存起来,空闲的时候再慢慢写入,只有调用close()
方法时,操作系统才保证把没有写入的数据全部写入磁盘,如果忘记调用close()
方法,那么很有可能数据只有一部分写入到了磁盘,造成数据的丢失。所以,还是用方式二:with 语句保险。
以'w'
方式写文件的时候,如果文件原来已经存在,那么会将原来的数据覆盖,可以传入'a'
以追加的方式写入文件。
# 方式一:
f = open("d:/TestData/test.txt", "w")
f.write("Hello world!)
f.close()
# 方式二:以追加的方式写入文件,并自动关闭文件
with open("d:/TestData/test.txt", "wa") as f_obj:
f.write("Hello world!")
三. StringIO 和 BytesIO
- StringIO 是在内存中读写 String
BytesIO 是在内存中读写 Byte
- StringIO
# 方式一:
from io import StringIO
f = StringIO()
f.write("Hello ")
f.write("world!")
print(f.getvalue()) # 获取值
# 方式二:
from io import StringIO
f = StringIO("Hello world!")
f.getvalue() # 获取值
- BytesIO
StringIO 操作的只能是 string,如果要操作二进制数据,就需要使用 BytesIO。
# 方式一:
from io import BytesIO
f = BytesIO()
f.write("中文".encode("utf-8"))
print(f.getvalue())
# 方式二:
from io import BytesIO
f = BytesIO(b'\xe4\xb8\xad\xe6\x96\x87')
print(f.getvalue())
四、操作文件和目录
- 如果要对系统的文件和目录进行操作,则需要引入
os
模块
import os
print(os.name) # 获取操作系统的类型
# Note: 如果是 posix,说明系统是 Linux/Unix/Mac OS X, 如果是 nt,就是 Windows 系统
print(os.uname()) # 获取系统的详细信息. Note: 注意,这个函数在 Windows 系统上是不提供的
- 查看环境变量
import os
print(os.environ) # 打印系统所有环境变量的值
获取某个环境变量的值,可以调用 --> os.environ.get('key')
import os
print(os.environ.get('PATH')) # 打印环境变量中 PATH 的值
# 打印环境变量中 Test 的值,如果没有此值,则用 default 代替
print(os.environ.get('Test', 'default'))
- 操作文件和目录
操作文件和目录的函数一部分放在os
模块中,一部分放在os.path
模块中
- 查看、创建、删除目录
Note: 对路径的合并和拆分并不要求目录和文件真实存在,它们只是对字符串进行操作
import os
# 查看当前目录的绝对路径
print(os.path.abspath('.'))
# 把两个路径合成一个路径打印出来
print(os.path.join('d:/testdir', 'aa')) # 打印 ‘d:/testdir/aa’
# 创建目录
os.mkdir("d:/testdir") # 此方法不可以级联创建
os.makedirs("d:/testdir/aa") # 级联创建
# 删除一个目录
os.rmdir("d:/testdir") # 不可级联删除
os.removedirs("d:/testdir/aa") # 级联删除
# 分拆目录
# 1. 获取最后一个文件或者目录
print(os.path.split("d:/testdir/file.txt")) # 打印 --> ('d:/testdir', 'file.txt')
# 2. 获取文件扩展名
print(os.path.splitext("d:/testdir/file.txt")) # 打印 --> ('d:/testdir/file', '.txt')
- 文件的删除和重命名
# 文件重命名
os.rename("test.txt", "test.py")
# 删除文件
os.remove("test.py")
- 文件的复制
由于os
模块不提供文件的复制操作,可以用shutil
模块来实现复制文件的操作
import shutil
shutil.copyfile("d:/testdir/file.txt", "d:/file.txt")