zoukankan      html  css  js  c++  java
  • [python][LXF][Notes]文件读写及序列化

    reference website:

    文件读写

    https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001431917715991ef1ebc19d15a4afdace1169a464eecc2000 

    python 帮助文档:

        ========= ===============================================================
        Character Meaning
        --------- ---------------------------------------------------------------
        'r'       open for reading (default)
        'w'       open for writing, truncating the file first
        'x'       create a new file and open it for writing
        'a'       open for writing, appending to the end of the file if it exists
        'b'       binary mode
        't'       text mode (default)
        '+'       open a disk file for updating (reading and writing)
        'U'       universal newline mode (deprecated)
        ========= ===============================================================

    'r': 读

    'w':写

    'a':追加

    'r+' == r+w(可读可写(从头覆盖写,新写了多少字节就从头覆盖多少字节),文件若不存在就报错(IOError))

    'w+' == w+r(可读可写(覆盖写,不管文件里面有什么都删了重写),文件若不存在就创建)

    'a+' ==a+r(可追加可写(在最后追加),文件若不存在就创建)

    1.读文件

    #path = 文件名(相对路径/绝对路径)

    path = 'D:\Python\workspace\test.txt'

    1 >>> f = open(path,'r')
    2 >>> f.read()
    3 'Hello
    World!'
    4 >>> f.close()

    但是如果打开文件失败,后面的f.close()就不会调用。需要用with语句来实现。

    >>> with open(path,'r') as f:
        print(f.read())
    
    Hello
    World!

    这种方式和try...finally(本文省略)是一样的,用with语句代码更简洁,且不必调用f.close()

    read() #一次性读取文件全部内容

    read(size) #每次最多读取size个字节的内容

    readline() #每次读取一行内容

    readlines() #一次读取所有内容并返回list

    >>> with open(path,'r') as f:
        print(f.read(3))
    
    Hel
    
    >>> with open(path,'r') as f:
        print(f.readline())
    
    Hello
    
    >>> with open(path,'r') as f:
        print(f.readlines())
        
    ['Hello
    ', 'World!']

    前面讲的默认都是读取文本文件,并且是UTF-8编码的文本文件。要读取二进制文件,比如图片、视频等等,用'rb'模式打开文件即可。

    2.写文件

    >>> with open(path,'w') as f:
        f.write('Hello
    World!')

    in test.txt: (会读取转义字符)

    Hello
    World!

    >>> with open(path,'a') as f:
        f.write(r'
    welcome!')

    'a'以追加的方式写。字符串前面加'r',不会读取转义字符。

    so, in test.txt:

    Hello
    World! welcome!

    >>> with open('test_create.txt','x') as f_new:
        f_new.write('test para x')

    'x' 创建一个新file,只能写(不能读)。

     序列化

    reference website:

    https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/00143192607210600a668b5112e4a979dd20e4661cc9c97000

    3.1 import pickle

    用pickle.dumps()把任意对象序列化成一个二进制bytes。或者用pick.dump(object,file)直接把对象序列化以后写入一个file-like object:(这里一个是dump一个是dumps)

    >>> d = dict(name='Chris',age=18, score=100)
    >>> pickle.dumps(d)
    b'x80x03}qx00(Xx04x00x00x00nameqx01Xx05x00x00x00Chrisqx02Xx05x00x00x00scoreqx03KdXx03x00x00x00ageqx04Kx12u.'
    >>> f = open('output.txt','xb')
    >>> pickle.dump(d,f)
    >>> f.close()

    必须以二进制方式打开,否则会报错:

    >>> f = open('output.txt','w')
    >>> pickle.dump(d,f)
    Traceback (most recent call last):
      File "<pyshell#139>", line 1, in <module>
        pickle.dump(d,f)
    TypeError: write() argument must be str, not bytes

    反序列化:

    pickle.load()

    >>> f = open('output.txt','rb')
    >>> d = pickle.load(f)
    >>> f.close()
    >>> d
    {'name': 'Chris', 'score': 100, 'age': 18}

    pickle.loads()

    >>> pickle_bytes = pickle.dumps(d)
    >>> pickle.loads(pickle_bytes)
    {'name': 'Chris', 'score': 100, 'age': 18}

    3.2 import json

    方便在不同的编程语言传递对象。JSON表示出来的是一个字符串,可以被所有语言读取。JSON是一种标准格式,比XML更快,可以直接在Web页面中读取。

    JSON表示的对象就是标准的JavaScript语言的对象,JSON和Python内置的数据类型对应如下:

    JSON类型 Python类型
    {} dict
    [] list
    "string" str
    1234.56 int或float
    true/false True/False
    null None
    >>> import json
    >>> json.dumps(d)
    '{"name": "Chris", "score": 100, "age": 18}'
    >>> type(json.dumps(d))
    <class 'str'>

    可以和pickle.dumps()的结果对比:

    pickle.dumps()序列化出来的是自然语言不可读的一串二进制(bytes).

    json.dumps() 返回一个str,内容就是标准的JSON。类似的,dump()方法可以直接把JSON写入一个file-like object

    反序列化:

    json.loads()方法把JSON的字符串反序列化或者对应的load()方法从一个file-like object中读取字符串并且反序列化:

    >>> json_str = json.dumps(d)
    >>> json.loads(json_str)
    {'name': 'Chris', 'score': 100, 'age': 18}

    JSON的dumps()方法提供了很多可选参数来定制JSON序列化。

    可选参数default就是把任意一个对象编程可序列为JSON的对象。

    举个栗子:

     1 class Student(object): #class Student
     2     def __init__(self, name, age, score):
     3         self.name = name
     4         self.age = age
     5         self.score = score
     6 
     7 s = Student('Chris', 18, 100) #实例一个Student类的对象s
     8 
     9 def student2dict(std): #把class Student转换为一个可序列为JSON的对象
    10     return {
    11         'name': std.name,
    12         'age': std.age,
    13         'score': std.score
    14     }
    15 
    16 #Student先被student2dict转换为一个dict,然后再顺利序列化为JSON
    17 print(json.dumps(s, default=student2dict)) 
    18 #任意class都有__dict__属性,它就是一个dict,所以可以直接这样用
    19 print(json.dumps(s, default=lambda obj: obj.__dict__))

    output:

    {"age": 18, "score": 100, "name": "Chris"}
    {"age": 18, "score": 100, "name": "Chris"}

    同样的反序列化,也要有一个转换函数负责把dict转换为Student的实例:

    1 def dict2student(d):
    2     return Student(d['name'], d['age'], d['score'])
    3 
    4 json_str = json.dumps(s, default=lambda obj: obj.__dict__)
    5 #loads()方法首先转换出一个dict对象,然后通过传入的object_hook函数,把dict转换为Student实例
    6 print(json.loads(json_str, object_hook=dict2student))

     output:

    <__main__.Student object at 0x00000000026B0EB8>

  • 相关阅读:
    [SNOI2019]数论
    [HNOI2019]校园旅行
    [TJOI2019]唱、跳、rap和篮球
    [Ctsc2015]misc
    [IOI2018] meetings 会议
    [ZJOI2019]语言
    51nod1600 Simple KMP
    [APIO2013]道路费用
    [FJOI2018]领导集团问题
    [ZJOI2012]小蓝的好友
  • 原文地址:https://www.cnblogs.com/hopping/p/7656537.html
Copyright © 2011-2022 走看看