Python 系统、IO、序列化

2020-01-16  本文已影响0人  李霖弢

注意,python中各种相对路径都相对于项目的工作目录,默认情况下即为项目的启动目录

读写文件

读写文件是最常见的IO操作。Python内置了读写文件的函数,用法和C是兼容的。

f = open('/Users/michael/test.txt', 'w+', encoding='utf-16', errors='replace')
f.write("hello")
f.seek(0)
print(f.read())

当我们写文件时,操作系统可能会放到内存缓存起来,空闲的时候再慢慢写入。只有调用close()方法时,操作系统才保证把没有写入的数据全部写入磁盘。
由于文件读写时都有可能产生IOError,一旦出错,后面的close就不会调用,应保证无论是否出错都能正确地关闭文件:

try:
    f = open('/path/to/file', 'r')
    print(f.read())
except BaseException as err:
    print(err)
finally:
    if f:
        f.close()

或使用with语句无论是否出错都会自动调用close()方法:

with open('/path/to/file', 'r') as f:
    print(f.read())
从当前指针处向后读

调用read会一次性读取文件的全部内容(但如内容过多会超出内存)
调用read(size)方法,每次最多读取size个字节
调用readline()每次读取一行
调用readlines()一次读取所有内容并按行返回list

for line in f.readlines():
    print(line.strip()) # 把末尾的'\n'删掉
二进制文件

要读取二进制文件,比如图片、视频、文件等,用带b的模式打开或输入即可:

with open(fileName, 'wb') as activeFile:
    for chunk in res.iter_content(len(res.content)):
        activeFile.write(chunk)

内存中读写

在内存中创建的file-like Object,常用作临时缓冲。
通过getvalue可以获取到完整内容(无视指针位置)
write写入的内容可以互相叠加,但会覆盖初始化时的内容

StringIO

读写str

from io import StringIO
f = StringIO('A')
f.write('B')
f.write('C')
print(f.getvalue())#BC
BytesIO

读写bytes

from io import BytesIO
f = BytesIO(b'\xe4\xb8\xad\xe6\x96\x87')
print(f.getvalue())#b'\xe4\xb8\xad\xe6\x96\x87'
f.seek(0)
print(f.read())#b'\xe4\xb8\xad\xe6\x96\x87'

OS

查看操作系统信息
import os
>>>os.name
Linux/Unix/Mac为posix,Windows为nt。
>>>os.environ
查看系统环境变量
路径操作
for root, dirs, files in os.walk(path):
    pass

以下方法只是字符串处理,不管是否真存在该路径

import os
os.path.join('/Users/michael', 'testdir')
'/Users/michael/testdir'
os.path.splitext('/path/to/file.txt')
('/path/to/file', '.txt')
新增/删除/改名
# 创建目录
os.mkdir('/Users/testdir')
os.makedirs('/Users/testdir/a/b/c')#创建多级目录
# 删除空目录
os.rmdir('/Users/testdir/a/b/c')
os.removedirs('/Users/a/b/c')#删除多级空目录
# 重命名目录/文件:
os.rename('test.txt', 'test.py')
# 删除文件:
os.remove('test.py')

file-like Object

拥有read方法的对象均可视为file-like Object,如open打开的文件、StringIO对象、BytesIO对象、满足条件的自定义对象

class FLO():
    content = ""
    def read(self):
        return self.content
    def write(self, e):
        self.content += e

序列化

我们把变量从内存中变成可存储或传输的过程称之为序列化,序列化之后的内容才可以写入磁盘,或者通过网络传输到别的机器上。
反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即unpickling。

pickle

pickle模块只能用于Python,并且可能不同版本的Python彼此都不兼容,因此不推荐使用

json
JSON类型 Python类型
{} dict
[] list
"string" str
1234.56 int或float
true/false True/False
null None

通过json.dumps可将以上Python类型转为json字符串并返回,或通过json.dump将其写入一个 file-like Object。

import json
d = dict(name='Bob', age=20, score=88)
myJson = json.dumps(d)
print(myJson)#{"name": "Bob", "age": 20, "score": 88}

with open("1.txt", "w+") as f:
    json.dump(d, f)
    f.seek(0)
    print(f.read())#{"name": "Bob", "age": 20, "score": 88}

class FLO():
    content = ""
    def read(self):
        return self.content
    def write(self, e):
        self.content += e
flo = FLO()
json.dump(d, flo)
print(flo.read())#{"name": "Bob", "age": 20, "score": 88}

通过json.loads把JSON反序列化为Python对象并返回,或通过json.load从file-like Object中读取字符串并反序列化:

json_str = '{"age": 20, "score": 88, "name": "Bob"}'
print(json.loads(json_str))#{"name": "Bob", "age": 20, "score": 88}

with open("1.txt", "r") as f:
    print(json.load(f))#{"name": "Bob", "age": 20, "score": 88}

class FLO():
    content = ""
    def read(self):
        return self.content
    def write(self, e):
        self.content += e
flo = FLO()
flo.content = '{"name": "Bob", "age": 20, "score": 88}'
print(json.load(flo))#{"name": "Bob", "age": 20, "score": 88}

对于不包含在上述列表中的对象(如自定义类的实例),可以在序列化时配置default或在反序列化时配置object_hook,先转化为dict再通过该配置的函数转化为目标

json.dumps(s, default=lambda obj: obj.__dict__)
上一篇下一篇

猜你喜欢

热点阅读