读文件
f = open('/test/aaa.txt', 'r') # 使用open()方法打开一个文件赋值给f对象
f.read() # 使用read()方法读取文件内容
f.close() # 最后一步是调用close()方法关闭文件
如果文件不存在会抛出IOError,一旦出错,后面的f.close()就不会调用。所以,为了保证无论是否出错都能正确地关闭文件,需要使用with语句来自动调用close()方法:
with open('/test/aaa.txt', 'r') as f:
print(f.read().strip()) # strip()方法用来删除末尾的'\n'
open('/test/ttt.jpg', 'rb').read() # 读取二进制文件,比如图片、视频等等
open('/test/gbk.txt', 'rb', encoding='gbk').read() # 读取GBK编码的文件
open('/test/gbk.txt', 'r', encoding='gbk', errors='ignore') # 如果遇到编码错误后如何处理,这里处理是直接忽略
写文件
写文件和读文件是一样的,唯一区别是调用open()函数时,传入标识符'w'或者'wb'表示写文本文件或写二进制文件:
#将文本写入文件
with open('/test/test.txt', 'w') as f:
f.write('Hello, world!')
#将文本追加到文件
with open('/test/test.txt', 'a') as f:
f.write('Hello, world!')
StringIO
StringIO就是在内存中读写str:
from io import StringIO
f = StringIO() # 创建一个StringIO
f.write('hello') # 写入字符串 hello
f.write(' ')
f.write('world')
print(f.getvalue()) # => hello world getvalue()方法用于获得写入后的str
BytesIO
BytesIO是在内存中操作二进制数据:
from io import BytesIO
f = BytesIO()
f.write('中文'.encode('utf-8'))
print(f.getvalue())
操作文件和目录
Python内置的os模块也可以直接调用操作系统提供的接口函数。
import os
# 系统
print(os.name) # 操作系统类型
print(os.uname()) # 获取详细的系统信息,注意uname()函数在Windows上不提供。
print(os.environ) # 获取操作系统中定义的环境变量
print(os.environ.get('PATH')) # 单独获取PATH这个变量
# 目录
print(__file__) # 获取当前脚本的执行路径
a = os.path.dirname(__file__)
print(a) # 当前脚本所在目录
print(os.path.dirname(a)) # 当前脚本的上一级路径
print(os.path.abspath('.')) # 取当前脚本所在的绝对路径
print(os.path.abspath('..')) # 当前脚本所在的上一级路径
os.mkdir('/data/www/test') # 创建目录
os.rmdir('/data/www/test') # 删除目录
os.path.join('aa', 'bb', 'cc') # => aa/bb/cc 拼接路径
print(os.path.split(/aa/bb/t.py)) # => ('/aa/bb', 't.py') 拆解路径
# 文件
os.rename('a.txt', 'b.py') # 对文件重命名
os.remove('test.py') # 删除文件
# 文件复制
import shutil
shutil.copyfile('a.py', 'b.py')
列出当前目录下的所有目录:
[x for x in os.listdir('.') if os.path.isdir(x)]
列出所有.py文件:
[x for x in os.listdir('.') if os.path.isfile(x) and os.path.splitext(x)[1]=='.py']
目录遍历器:
os.walk()
详细参考:http://www.runoob.com/python3/python3-os-walk.html
Python的os模块封装了操作系统的目录和文件操作,要注意这些函数有的在os模块中,有的在os.path模块中。
序列化
序列化(Python中叫pickling)
内存中的对象 -----------------------------------> 可存储或传输
反序列化(unpickling)
序列化的对象 -----------------------------------> 内存中的对象
Python提供了pickle模块来实现序列化:
import pickle
d = dict(name='sunk', age=20, score=88)
# 把一个对象序列化之后打印出来
print(pickle.dumps(d))
# 把一个对象序列化后写入到文件
with open('./aaa.txt', 'wb') as f:
pickle.dump(d, f)
# 从磁盘文件中读取到内存中
with open('./aaa.txt', 'rb') as f:
a = pickle.load(f)
print(a)
只能用Pickle保存那些不重要的数据,因为版本不兼容问题可能导致数据不能反序列化。
JSON
JSON和Python内置的数据类型对应如下:
JSON类型
Python类型
{}
dict
[]
list
"string"
str
1234.56
int或float
true/false
True/False
null
None
import json
d = dict(name='Bob', age=20, score=88)
# 把python对象转为JSON
print(json.dumps(d))
# 把对象转为JSON并存储到文件
with open('./111.txt', 'w') as f:
json.dump(d, f)
# 从文件中读取JSON数据
with open('./111.txt', 'r') as f:
print(json.load(f))
# 从文件中读取JSON数据转为python对象
with open('./111.txt', 'r') as f:
a = json.loads(f.read())
print(a)
# JSON如果包含中文字符
obj = dict(name='小明', age=20)
print(json.dumps(obj, ensure_ascii=True)) # => {"name": "\u5c0f\u660e", "age": 20}
print(json.dumps(obj, ensure_ascii=False)) # => {"name": "小明", "age": 20}
JSON和class对象之间的转换
定义一个学生类:
import json
class Student(object):
def __init__(self, name, age, score):
self.name = name
self.age = age
self.score = score
a = Student('张三', '20', 99)
类的实例有一个__dict__属性用来存储实例变量,它是一个dict对象:
print(a.__dict__) # => {'name': '张三', 'age': '20', 'score': 99}
用dumps的default参数指定一个函数转换类对象为dict对象,然后就可以转换为json数据:
print(json.dumps(a, default=lambda x: x.__dict__))
下面例子是把JSON转为类的实例对象:
import json
class Student(object):
def __init__(self, name, age, score):
self.name = name
self.age = age
self.score = score
def info(self):
return '姓名:{}\n年龄:{}岁\n成绩:{}分'.format(self.name, self.age, self.score)
a = Student('张三', '20', 99)
print(a.info())
print('----------------------------')
json_str = '{"age": 22, "score": 88, "name": "李四"}'
b = json.loads(json_str, object_hook=lambda x: Student(x['name'], x['age'], x['score']))
print(b.info())
输出:
姓名:张三
年龄:20岁
成绩:99分
----------------------------
姓名:李四
年龄:22岁
成绩:88分