上面我们讲了如何对文件(无论是硬盘中还是内存中)进行读写,如果我们想对文件还有进行删除和创建的操作,要怎么办呢?
1)对目录和文件操作
这里就要 用到一个模块,os。os模块为python提供了一个操作系统的接口函数,可以让我们对系统中的文件进行操作,但是这个模块是与系统相关的。也就是有的方法在不同的系统当中,可能失效。
(1)识别出操作系统
这里,我们先识别出操作系统。示例代码如下:
import os
os.name
输出结果:
'nt'
这里的Nt代表这是window系统,如果MacOs或者是linuxOS的话,则是posix。如果我们想知道,系统的详细信息,我们采用os.uname()方法。这里windows系统不支持这个接口。所以就不示范了,输出结果如下:
AttributeError: module 'os' has no attribute 'uname'
(2)对目录和文件进行操作
(1)目录
我们要想操作一个文件或者目录,首先得知道要操作的目录在哪里。这里我们调用os.path.abspath()方法,就可以知道当前所属目录了。示例代码如下:
>>> os.path.abspath('.')
'C:\\Users\\Administrator'
接下来是对目录名进行拼接操作,我们这里用os.path.join()。示例代码:
>>> os.path.join('/Users/Administrator','testdir')
'/Users/Administrator\\testdir'
我们也可以拆分路径,用os.path.split()
>>> os.path.split('/Users/michael/testdir/file.txt')
('/Users/michael/testdir', 'file.txt')
我们可以用os.mkdir(make direction)函数来创建目录,用os.rmdir(remove direction)函数来删除目录。示例代码如下:
>>> os.mkdir('/Users/Administrator/testdir')
>>> os.rmdir('/Users/Administrator/testdir')
(2)文件
重命名一个文件,可以用os.rename()函数,示例代码如下:
os.rename('text.txt','text.c')
删除一个文件,os.remove(),示例代码如下:
>>> os.remove('text.c')
我们也可以拆分扩展名,用os.path.splitext(),示例代码如下;
>>> os.path.splitext('/Users/Administrator/text.txt')
('/Users/Administrator/text', '.txt')
(3)过滤
我们可以利用python特性来过滤文件,先列出当前所有目录,示例代码如下:
>>> [x for x in os.listdir('.') if os.path.isdir(x)]
这里我们用了一个生成器和一个listdir方法,对目录进行遍历。然后,判断目录是否为空,输出。
接下来,过滤指定类型文件。示例代码如下:
>>> [x for x in os.listdir('.') if os.path.isfile(x) and os.path.splitext(x)[1]=='.txt']
两个判断,一个判断文件存在,一个判断.txt格式。
总结,我个人觉得该部分内容比较鸡肋,通常情况下,我们不需要这么麻烦对文件名和目录修改操作,只需关注文件在哪里和怎么读取就可以了。
(4)压缩文件操作
python提供了gzip函数,来操作。示例代码如下:
f=gzip.open('mnist.pkl.gz','rb')
一般,这个只是在当前目录下查询。
2)序列化
此部分内容很重要,因为在机器学习源码中见到过对pickel函数的操作,在python2.7的版本中是:cPickel模块。
(1)定义
首先说,什么是序列化?序列化就是将内存中的数据,存储到硬盘当中。
(2)操作
示例代码如下:
>>> import pickle
>>> d=dict(name='quinn',age=20,score=88)
>>> pickle.dumps(d)
b'\x80\x03}q\x00(X\x04\x00\x00\x00nameq\x01X\x05\x00\x00\x00quinnq\x02X\x03\x00\
x00\x00ageq\x03K\x14X\x05\x00\x00\x00scoreq\x04KXu.'
>>> f=open('text.txt','wb')
>>> pickle.dump(d,f)
>>> f.close()
我们这里先将一个变量d序列化,然后打开文件,并写入文件。再用pickle.dump函数将d写入到f中。最后关闭文件,释放内存。
3)跨语言传输
(1)
我们之前讲了那么多,为什么要将数据序列化呢?为什么要这么麻烦呢?因为,不同语言之间变量格式是不同的,要想在不同语言之间传递数据,需要将其标准化,如:xml格式等标准格式。这里我们用JSON格式,这种格式不仅是javascript的格式,还是一种标准格式。示例代码如下:
# -*- coding: utf-8 -*-
#!/usr/bin/env python3
import json
d=dict(name='Bob',age=20,score=88)
print(json.dumps(d))
输出结果:
{"name": "Bob", "age": 20, "score": 88}
这里,我们可以看到字典数据,已经变为{}输出了。这是在Javascript当中对应的字典格式。
注意:
要将JSON反序列化,可以用load或者loads方法。
示例代码如下:
json_str = '{"age": 20, "score": 88, "name": "Bob"}'
json.loads(json_str)
(2)
那么对实例或者类怎么转化呢?
首先,我们要先将实例转化为字典。这里要创建一个转化函数:
def student2dict(std):
return {
'name': std.name,
'age': std.age,
'score': std.score
}
然后,再将实例转化。示例代码如下:
# -*- coding: utf-8 -*-
#!/usr/bin/env python3
import json
class Student(object):
def __init__(self, name, age, score):
self.name = name
self.age = age
self.score = score
def student2dict(std):
return {
'name': std.name,
'age': std.age,
'score': std.score
}
s = Student('Bob', 20, 88)
print(json.dumps(s, default=student2dict))
这里,我们用了default参数,他的作用就是把任意一个对象转化成可序列化的对象。但是如果下次遇到别的类,就无法使用了。
这里,我们可以用lamada匿名变量,示例代码如下:
print(json.dumps(s, default=lambda obj: obj.__dict__))
希望有志同道合的小伙伴关注我的公众平台,欢迎您的批评指正,共同交流进步。