• 【Python】IO编程


    文件读写

    StringIO和BytesIO

    操作文件和目录

    序列化

    学习廖老师的py官网的笔记

    1、stream的概念。数据交换通常需要建立两根“水管”。

    2、同步IO和异步IO。异步性能高,但是编程模型复杂。

    3、操作IO的功能是操作系统提供的!不论是Java还是Pyton都只是将低级接口封装起来供开发者使用。

    【文件读写】

    读文件

    1、简单的

    >>> f = open('ask.txt', 'r')
    >>> f.read()
    '我想你最近一定很忙。'
    >>>

    但是要记得关掉(文件对象会占操作系统的资源)

    >>> f.close()

    但是有时候读文件可能会抛出错误,例如:文件不存在。为了保证最后一定会把文件关掉,必须使用一定会执行的finally语句。

    try:
        f = open('ask.txt', 'r')
        print(f.read())
    finally:
        if f:
            f.close()

    有一种等价写法:

    with open('ask.txt') as f:
        print(f.read())

    2、逐行读取。

    with open('ask.txt', 'r') as f:
        for line in f.readlines():
            print(line.strip()) #print自带换行的效果,这里的strip把'
    '去掉。

    file-like Object:有read方法的对象。

    读取二进制:

    # -*- coding: utf-8 -*-
    # read byte
    # 默认情况下都是读取文本文件
    # 如果要读取图片等文件
    with open('a.png', 'rb') as f:
        print(f.read())

    读取非UTF-8编码的文件:

     

    errrors参数表示遇到编码错误直接忽略。

    写文件

    类比读文件就可以了。

    简单的例子

    >>> with open('ask.txt', 'w') as f:
    ...     f.write('所以你只要看前三个字就好')
    ...
    12
    >>> with open('ask.txt', 'w', errors='ignore') as f:
    ...     f.write('所以你只要看前三个字就好')
    ...
    12

    不知道为什么会有返回值。

    【StringIO和BytesIO】

    在内存中读写。

    StringIO

    >>> from io import StringIO
    >>> f = StringIO()
    >>> f.write('床前明月光')
    5
    >>> f.write(' 疑是地上霜')
    6
    >>> f.getvalue()
    '床前明月光 疑是地上霜'

    可以理解为在内存中的一个“文件”,因为操作StringIO和操作file没有太大区别:

    >>> f = StringIO('i
    miss
    you!')
    >>> while True:
    ...     s = f.readline() # 读取掉一行
    ...     if s == '': # 如果已经读完
    ...             break
    ...     print(s.strip())
    ...
    i
    miss
    you!

    BytesIO

    >>> from io import BytesIO
    >>> f = BytesIO('abc123')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: a bytes-like object is required, not 'str'
    >>> f = BytesIO(b'abc123')
    >>> f.read()
    b'abc123'

    【操作文件和目录】

    os模板是操作系统相关的。

    >>> import os
    >>> os.name
    'nt'

    环境变量

    >>> os.environ
    environ({'SYSTEMDRIVE': 'C:', 'ALLUSERSPROFILE': 'C:\ProgramData', 'PUBLIC': 'C:\Users\Public', 'LOCALAPPDATA': 'C:\Users\mdzz\AppData\Local', 'USERDOMAIN': 'LAPTOP-QGECNCGO', 'SYSTEMROOT': 'C:\WINDOWS', 'PSMODULEPATH': 'C:\Program Files\WindowsPowerShell\Modules;C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules', 'TMP': 'C:\Users\mdzz\AppData\Local\Temp', 'COMSPEC': 'C:\WINDOWS\system32\cmd.exe', 'NUMBER_OF_PROCESSORS': '4', 'PROCESSOR_IDENTIFIER': 'Intel64 Family 6 Model 94 Stepping 3, GenuineIntel', 'PATH': 'C:\ProgramData\Oracle\Java\javapath;C:\Program Files (x86)\Intel\iCLS Client\;C:\Program Files\Intel\iCLS Client\;C:\windows\system32;C:\windows;C:\windows\System32\Wbem;C:\windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;C:\Program Files\MySQL\MySQL Server 5.5\bin;C:\maven\apache-maven-3.3.9\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\MinGW\bin;C:\Program Files\Java\jdk1.8.0_101\bin;C:\Users\mdzz\AppData\Local\Programs\Python\Python35\Scripts\;C:\Users\mdzz\AppData\Local\Programs\Python\Python35\;C:\Users\mdzz\AppData\Local\Microsoft\WindowsApps;C:\Users\mdzz\AppData\Roaming\npm;C:\Users\mdzz\AppData\Local\atom\bin', 'LOGONSERVER': '\\LAPTOP-QGECNCGO', 'MOZ_PLUGIN_PATH': 'C:\Program Files (x86)\Foxit Software\Foxit Reader\plugins\', 'PROGRAMFILES': 'C:\Program Files', 'ONLINESERVICES': 'Online Services', 'USERNAME': 'mdzz', 'PROCESSOR_LEVEL': '6', 'PROMPT': '$P$G', 'HOMEPATH': '\Users\mdzz', 'PATHEXT': '.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC', 'PROGRAMFILES(X86)': 'C:\Program Files (x86)', 'COMPUTERNAME': 'LAPTOP-QGECNCGO', 'WINDIR': 'C:\WINDOWS', 'ONEDRIVE': 'C:\Users\mdzz\OneDrive', 'USERDOMAIN_ROAMINGPROFILE': 'LAPTOP-QGECNCGO', 'COMMONPROGRAMFILES': 'C:\Program Files\Common Files', 'MAVEN_HOME': 'C:\maven\apache-maven-3.3.9', 'PROGRAMW6432': 'C:\Program Files', 'TEMP': 'C:\Users\mdzz\AppData\Local\Temp', 'VS140COMNTOOLS': 'C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools\', 'JAVA_HOME': 'C:\Program Files\Java\jdk1.8.0_101', 'PROGRAMDATA': 'C:\ProgramData', 'COMMONPROGRAMW6432': 'C:\Program Files\Common Files', 'CLASSPATH': '.;C:\Program Files\Java\jdk1.8.0_101lib;C:\Program Files\Java\jdk1.8.0_101lib\tools.jar', 'USERPROFILE': 'C:\Users\mdzz', 'REGIONCODE': 'APJ', 'PLATFORMCODE': 'KV', 'HOMEDRIVE': 'C:', 'PROCESSOR_REVISION': '5e03', 'APPDATA': 'C:\Users\mdzz\AppData\Roaming', 'OS': 'Windows_NT', 'PROCESSOR_ARCHITECTURE': 'AMD64', 'COMMONPROGRAMFILES(X86)': 'C:\Program Files (x86)\Common Files'})

     获取某个具体环境变量的值:

    >>> os.environ.get('PATH')

    操作文件和目录

    操作文件和目录的函数一部分放在os模块中,一部分放在os.path模块中。

    操作文件和目录基本可以映射为在命令行下操作文件和目录:

    >>> import os
    >>> os.path.abspath('.')
    'D:\labs'

    创建目录:

    >>> os.path.join('D:\labs', 'TestDir') # 这个时候没有真的创建
    'D:\labs\TestDir'
    >>> os.mkdir('D:\labs\TestDir') # 真的创建了
    >>> os.rmdir('D:\labs\TestDir') # 删掉!

    之所以使用os.path.join()函数,是因为在不同操作系统上文件分隔符是不同的,这样可以正确处理。

    同样,要拆分文件路径,也需要使用特殊的函数os.path.split(),os.path.splitext()可以直接获得文件拓展名。

    # 对文件重命名:
    >>> os.rename('test.txt', 'test.py')
    # 删掉文件:
    >>> os.remove('test.py')

    出当前路径下的所有文件:

    >>> [x for x in os.listdir('.')]
    ['2.cpp', '4.cpp', '5.cpp', 'a.exe', 'a.png', 'ask.txt', 'c++task', 'cpppojects3月六日', 'cpppojects3月 六日.rar', 'Dada', 'Employee', 'input.txt', 'javaDocTest', 'MyTest', 'MyTest.class', 'MyTest.java', 'output.txt', 'pictest', 'picture1.jpg', 'prog1.cpp', 'Sales_data.h', 'separatecp', 'student.sql', 'sum_test.py', 'sum_test.py.bak', 'test.py', 'test.py.bak', '__pycache__']

    筛选出文件夹:

    >>> [x for x in os.listdir('.') if os.path.isdir(x)]
    ['c++task', 'cpppojects3月六日', 'Dada', 'Employee', 'javaDocTest', 'MyTest', 'pictest', 'separatecp', '__pycache__']

    筛选出所有py文件:

    >>> [x for x in os.listdir('.') if os.path.isfile(x) and os.path.splitext(x)[1]=='.py']
    ['sum_test.py', 'test.py']

    【序列化】

    序列化:变量从内存中变成可存储或传输的过程。

    被叫做pickling、serialization、marshalling、flattening等。

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

     Pickle的问题和所有其他编程语言特有的序列化问题一样,就是它只能用于Python,并且可能不同版本的Python彼此都不兼容,因此,只能用Pickle保存那些不重要的数据.

    尝试:

    >>> import pickle
    >>> d = dict(name = 'xkfx', age = 19)
    >>> pickle.dumps(d)
    b'x80x03}qx00(Xx04x00x00x00nameqx01Xx04x00x00x00xkfxqx02Xx03x00x00x00ageqx03Kx13u.'
    >>> f = open('dump.txt', 'wb')
    >>> pickle.dump(d, f)
    >>> f.close()
    >>> f= open('dump.txt', 'rb')
    >>> d =  pickle.load(f)
    >>> f.close()
    >>> d
    {'name': 'xkfx', 'age': 19}

    JSON

    JSON是什么?

    -----JSON 是 JS 对象的字符串表示法,它使用文本表示一个 JS 对象的信息,本质是一个字符串。

    JSON是干嘛的?

    为什么是JSON?

     

    JSON与Python

    要在不同的语言中传递数据,就必须把数据序列化成标准格式。例如在Python和Java中交互数据。

    JSON比XML好一些。

    JSON表示的对象就是标准的JavaScript语言的对象.

    对应关系:

    Python内置的json模块提供了非常完善的Python对象到JSON格式的转换。JSON标准规定JSON编码是UTF-8。

    尝试:

    >>> import json
    >>> i = dict(name = 'xkfx', age = 19)
    >>> json.dumps(d)
    '{"name": "xkfx", "age": 19}' # 这个str是标准的JSON
    >>> str = '{"name": "xkfx", "age": 19}'
    >>> json.loads(str)
    {'name': 'xkfx', 'age': 19}

    对象的dumps()和loads()。

     1、尝试直接dumps()一个对象:

    import json
    
    class Student(object):
        def __init__(self, name, age, score):
            self.name = name
            self.age = age
            self.score = score
    
    
    s = Student('xkfx', 19, 20)
    print(json.dumps(s))

    抛出错误:

    s = Student('xkfx', 19, 20)
    print(json.dumps(s))

    2、失败的原因是dumps()不懂得如何将s引用的对象序列化。这样的话,只需要告诉dumps如何将对象序列化就可以了。

    def student2dict(std):
        return {
            'name' : std.name,
            'age' : std.age,
            'score' : std.score
        }
    
    s = Student('xkfx', 19, 20)
    print(json.dumps(s, default=student2dict))
    $ python test.py
    {"age": 19, "score": 20, "name": "xkfx"}

    3、但是,如果对于每个类都要写对应的序列化方法也未免太麻烦了。所以有一种偷懒的方法:

    print(json.dumps(s, default=lambda obj: obj.__dict__))

    每个对象自带有dict,通过.dict访问

    print(s.__dict__)
    print(json.dumps(s, default=lambda obj: obj.__dict__))
    python test.py
    {'score': 20, 'age': 19, 'name': 'xkfx'} # 原始dict
    {"score": 20, "age": 19, "name": "xkfx"} # 序列化成JSON

    4、反序列化也是同样的道理,loads不知道如何反序列化,必须传入一个方法告诉它怎么做,不同的是反序列化无法偷懒!:

    def dict2student(d):
        return Student(d['name'], d['age'], d['score'])
    
    json_data = '{"age": 19, "score": 20, "name": "xkfx"}'
    print(json.loads(json_data, object_hook=dict2student))
    <__main__.Student object at 0x0000022226F0B630>
  • 相关阅读:
    剑指 Offer 53
    Visual Studio Ultimate 2013
    手把手教你如何把java代码,打包成jar文件以及转换为exe可执行文件
    DirectX的Vertex Buffer顶点缓冲的理解和应用 Shader必知必会
    Qt5.2中的android环境搭建
    JavaScript的基础学习篇
    九月十月百度,迅雷,华为,阿里巴巴最新校招笔试面试三十题(10.18)
    十月下旬腾讯,网易游戏,百度迅雷校园招聘笔试题集锦(第271-330题)
    九月十月百度人搜,阿里巴巴,腾讯华为笔试面试八十题(第331-410题)
    十月上旬百度,阿里巴巴,迅雷搜狗最新面试七十题(第201-270题)
  • 原文地址:https://www.cnblogs.com/xkxf/p/6683391.html
Copyright © 2020-2023  润新知