1.IO编程
1.1 文件相关操作
  • 打开文件操作: 使用python内置的open()函数,参数为文件名和标示符,标示符r或rb代表着,w或wb代表着写或二进制文件写入
  • 如果要读取二进制文件,则需要使用rb的标示符来进行操作
>>> f=open('/usr/local/test.txt','r')
#获取二进制文件
>>> f=open('/tmp/test.txt','rb')
#写文件
>>> f=open('/tmp/test.txt','w') #
  • 使用read()函数进行读取操作,一次性读取文件的全部内容,如果文件太大,需要加参数read(size),读取指定大小的数据,也可使用readline()读取每一行内容,调用readlines()可以一次读取所有内容并按行返回list
  • read()方法不仅可以获取file,还可以对字节流,网络流,自定义流进行操作
>>> f.read()
  • 使用close()关闭文件
>>> f.close()

文件打开失败,会报出IOError错误,需要使用try……except…finally来处理,还可以简单的使用with方法来进行处理,可省略close()

with open('/path/test.txt','r') as f:
	print(f.read())
1.2 编码

要读取非utf-8编码的文件时,需要给open()函数指定编码

>>> f=open('/tmp/text.txt','r',encoding='gbk')

遇到有些编码不规范的文件,你可能会遇到UnicodeDecodeError,因为在文本文件中可能夹杂了一些非法编码的字符。遇到这种情况,open()函数还接收一个errors参数,表示如果遇到编码错误后如何处理。最简单的方式是直接忽略:

>>> f=open('/usr/local/test.txt','r',encoding='gbk',errors='ignore')
2. StringIo和BytesIO
  • StringIO;当要在内存中读取时str时

方法

>>> from io import StringIO
>>> f=StringIO()
>>> f.write('hello')
>>> print(f.getvalue())  #`getvalue()`方法用于获取写入后的str

要读取StringIO,可以用一个str初始化StringIO,然后,像读文件一样读取:

>>> from io import StringIO
>>> f=StringIO('hello\nhi\nGooge')
>>> while True:
	s=f.readlines()
	if s=='':
		break
  • BytesIO 如果要操作二进制数据,则需要使用BytesIO
>> from io import BytesIO
>>> f = BytesIO()
>>> f.write('中文'.encode('utf-8'))
6
>>> print(f.getvalue())
b'\xe4\xb8\xad\xe6\x96\x87'
3.操作文件和目录

python提供内置的os模块功能

前提引入os模块

  • 查看操作系统类别 ,如果是posix 说明系统为linux,unix,mac os ,如果是nt说明是windows
>>> import os
>>> os.name
>>> os.uname() # 获取系统的详细信息,但是在windows下不支持哦
  • 环境变量 可以使用os.environ来实现
>>> os.environ # 可以打印本机的环境变量
>>> os.environ.get(key) 可以获取某个变量的值
3.1 操作文件和目录

文件和目录一部分放在了os模块中,一部分放在了os.path模块中

  • 查看当前目录的绝对路径
>>> os.path.abspath('.')
  • 在某个目录下新建一个目录,首先把新目录的完整路径表示出来
>>> os.path.join('/tmp','testdir')
#然后创建一个目录
>>> os.mkdir('/tmp/testdir')
  • 删掉一个目录
>>> os.rmdir('/tmp/testdir')

当两个路径合并时,请使用os.path.join()这样可以保证不同操作系统间的路径分隔符是一样的,同理在进行路径分割的时候请使用os.path.split()进行分割

  • os.path.splitext()可以直接获取文件扩展名
>>> os.path.splitext('/tmp/test.txt')
('/tmp/test','.txt')

这些路径操作函数,不要求有真实的路径存在,它们只是对字符串进行操作而已

3.2 文件相关操作
  • 对文件重命名
>>> os.rename('test.txt','lnssm.txt')
  • 删除文件
>>> os.remove('test.py')
  • 复制文件 需要引入shutil模块 并使用copyfile()函数
4. 序列化

序列化:我们把变量从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening等等,都是一个意思。

序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上。

反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即unpickling。

Python提供了pickle模块来实现序列化。

  • 序列化 pickle.dumps()或者pickle.dump(),区别: pickle.dumps()方法可以把任一个对象序列化成一个bytes,而pickle.dump()可以序列化一个file-like object
>>>import pickle
>>> d=dict(name='lnssm',age=15)
>>> pickle.dumps(d)
#使用dump操作
>>> f=open('dump.txt','wb')
>>> pickle.dump(d,f)
>>> f.close()
  • 反序列化 是使用 pickle.loads()或者pickle.load()来操作,这里要与序列化函数进行对应
>>> f=open('dump.txt','rb')
>>> d=pickle.load(f)
>>> f.close()
>>>d

缺点: 只能在python语言中使用,别的语言不识别,需要使用json

4.2 json python内置的json模块提供了非常完善的python对象到josn格式的转换

dumps()方法返回一个str,内容是标准的json格式,dump()可以直接把json写入到一个file-like object中,要把json反序列成python对象,可以用loads()或load()

>>> import json
>>> d=dict(name='lnssm',age=19)
>>>json.dumps(d)

Python的dict对象可以直接序列化为JSON的{},不过,很多时候,我们更喜欢用class表示对象,比如定义Student类,然后序列化:

import json

class Student(object):
    def __init__(self, name, age, score):
        self.name = name
        self.age = age
        self.score = score

s = Student('Bob', 20, 88)
print(json.dumps(s))

运行代码,毫不留情地得到一个TypeError

Traceback (most recent call last):
  ...
TypeError: <__main__.Student object at 0x10603cc50> is not JSON serializable

别急,我们仔细看看dumps()方法的参数列表,可以发现,除了第一个必须的obj参数外,dumps()方法还提供了一大堆的可选参数:

这些可选参数就是让我们来定制JSON序列化。前面的代码之所以无法把Student类实例序列化为JSON,是因为默认情况下,dumps()方法不知道如何将Student实例变为一个JSON的{}对象。

可选参数default就是把任意一个对象变成一个可序列为JSON的对象,我们只需要为Student专门写一个转换函数,再把函数传进去即可

def student2dict(std):
    return {
        'name': std.name,
        'age': std.age,
        'score': std.score
    }