路漫漫其修远兮
吾将上下而求索

python学习:io操作,文件目录操作,json序列化

io操作
由于文件读写时都有可能产生IOError,一旦出错,后面的f.close()就不会调用。
所以,为了保证无论是否出错都能正确地关闭文件,我们可以使用try ... finally来实现:
try:
    f = open('/path/to/file', 'r')
    print(f.read())
finally:
    if f:
        f.close()
        
with open ('D:/python练习/file', 'w', encoding='gbk') as f:
    f.write('this is a computer\n 我的名字是什么')

with open ('D:/python练习/file', 'r', encoding='gbk') as f:
    a = f.read()
    print (a)

标识符'w'或者'wb'表示写文本文件或写二进制文件
可以反复调用write()来写入文件,但是务必要调用f.close()来关闭文件。当我们写文件时,操作系统往往不会立刻把数据写入磁盘,
而是放到内存缓存起来,空闲的时候再慢慢写入。只有调用close()方法时,操作系统才保证把没有写入的数据全部写入磁盘。忘记调
用close()的后果是数据可能只写了一部分到磁盘,剩下的丢失了。所以,还是用with语句来得保险
如果是配置文件,调用readlines()最方便:
要读取二进制文件,比如图片、视频等等,用'rb'模式打开文件即可


stringIO
# StringIO和BytesIO

# stringIO 比如说,这时候,你需要对获取到的数据进行操作,但是你并不想把数据写到本地硬盘上,这时候你就可以用stringIO
from io import StringIO
from io import BytesIO
def outputstring():
    return 'string \nfrom \noutputstring \nfunction'

s = outputstring()

# 将函数返回的数据在内存中读
sio = StringIO(s)
# 可以用StringIO本身的方法
print(sio.getvalue())
# 也可以用file-like object的方法
s = sio.readlines()
for i in s:
    print(i.strip())


# 将函数返回的数据在内存中写
sio = StringIO()
sio.write(s)
# 可以用StringIO本身的方法查看
s=sio.getvalue()
print(s)

# 如果你用file-like object的方法查看的时候,你会发现数据为空

sio = StringIO()
sio.write(s)
for i in sio.readlines():
    print(i.strip())

# 这时候我们需要修改下文件的指针位置
# 我们发现可以打印出内容了
sio = StringIO()
sio.write(s)
sio.seek(0,0)
print(sio.tell())
for i in sio.readlines():
    print(i.strip())

# 这就涉及到了两个方法seek 和 tell
# tell 方法获取当前文件读取指针的位置
# seek 方法,用于移动文件读写指针到指定位置,有两个参数,第一个offset: 偏移量,需要向前或向后的字节数,正为向后,负为
向前;第二个whence: 可选值,默认为0,表示文件开头,1表示相对于当前的位置,2表示文件末尾
# 用seek方法时,需注意,如果你打开的文件没有用'b'的方式打开,则offset无法使用负值哦



# stringIO 只能操作str,如果要操作二进制数据,就需要用到BytesIO
# 上面的sio无法用seek从当前位置向前移动,这时候,我们用'b'的方式写入数据,就可以向前移动了
bio = BytesIO()
bio.write(s.encode('utf-8'))
print(bio.getvalue())
bio.seek(-36,1)
print(bio.tell())
for i in bio.readlines():
    print(i.strip())




os.environ   查看环境变量,其实就是一个字典
os.environ.get('PATH')  查看path环境变量

目录操作
import os
a = os.path.abspath('.')
b = os.path.join(a,'test') 用系统自带的来拼接,而不是直接写路径,因为windows和linux斜线不同,不然不能跨平台
os.mkdir (b)
os.rmdir(b)

要拆分路径时,也不要直接去拆字符串,而要通过os.path.split()函数,这样可以把一个路径拆分为两部分,后一部分总是最后级别的目录或文件名:
>>> os.path.split('/Users/michael/testdir/file.txt')
('/Users/michael/testdir', 'file.txt')

把两个路径合成一个时,不要直接拼字符串,而要通过os.path.join()函数
拆分路径时,也不要直接去拆字符串,而要通过os.path.split()函数
os.rename('test.txt', 'test.py')
os.remove('test.py')

利用Python的特性来过滤文件。比如我们要列出当前目录下的所有目录,只需要一行代码:
>>> [x for x in os.listdir('.') if os.path.isdir(x)]
['.lein', '.local', '.m2', '.npm', '.ssh', '.Trash', '.vim', 'Applications', 'Desktop', ...]

要列出所有的.py文件,也只需一行代码:
>>> [x for x in os.listdir('.') if os.path.isfile(x) and os.path.splitext(x)[1]=='.py']
['apis.py', 'config.py', 'models.py', 'pymonitor.py', 'test_db.py', 'urls.py', 'wsgiapp.py']


把变量从内存中变成可存储或传输的过程称之为序列化,序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上
把变量内容从序列化的对象重新读到内存里称之为反序列化,即unpickling。
pickle.dumps()方法把任意对象序列化成一个bytes,然后,就可以把这个bytes写入文件。或者用另一个方法pickle.dump()直接把对
象序列化后写入一个file-like Object

import pickle
d = dict (name='andy', age=20, score=50)
print (d)
e = pickle.dumps(d)
print (e)
f = open ('dump.txt', 'wb')
pickle.dump(d, f)
f.close()

f = open ('dump.txt', 'rb')
g = pickle.load(f)
f.close()
print (g)

{'name': 'andy', 'age': 20, 'score': 50}
b'\x80\x03}q\x00(X\x04\x00\x00\x00nameq\x01X\x04\x00\x00\x00andyq\x02X\x03\x00\x00\x00ageq\x03K\x14X\x05\x00\x00\x00scoreq\x04K2u.'
{'name': 'andy', 'age': 20, 'score': 50}


json
如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,更好的方法是序列化为JSON
dumps()方法返回一个str,内容就是标准的JSON。类似的,dump()方法可以直接把JSON写入一个file-like Object
要把JSON反序列化为Python对象,用loads()或者对应的load()方法,前者把JSON的字符串反序列化,后者从file-like Object中读取字符串并反序列化

import json

d = dict (name='andy', age=20, score=98)
e = json.dumps(d)
print (d)
print (e)
f = json.loads(e)
print (f)

{'name': 'andy', 'age': 20, 'score': 98}
{"name": "andy", "age": 20, "score": 98}
{'name': 'andy', 'age': 20, 'score': 98}


默认情况下,dumps()方法不知道如何将Student实例变为一个JSON的{}对象,可选参数default就是把任意一个对象变成一个可序列
为JSON的对象,我们只需要为Student专门写一个转换函数,再把函数传进去即可
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,
        'scores': std.score
    }

s = student('bob', 20, 88)
a = json.dumps(s, default=student2dict)
print (a)

{"name": "bob", "age": 20, "scores": 88}

未经允许不得转载:江哥架构师笔记 » python学习:io操作,文件目录操作,json序列化

分享到:更多 ()

评论 抢沙发

评论前必须登录!