Python3(10) Python IO编程

本系列主要学习Python的基本使用和语法知识,后续可能会围绕着AI学习展开。
Python3 (1) Python语言的简介
Python3 (2) Python语法基础
Python3 (3) Python函数
Python3 (4) Python高级特性
Python3 (5) Python 函数式编程
Python3 (6) Python 模块
Python3 (7) Python 面向对象编程
Python3 (8) Python 面向对象高级编程
Python3 (9) Python 错误、调试和测试
Python3 (10) Python IO编程
这篇IO 编程,主要介绍Python 对文件的操作,文件流的输入输出,序列化操作 。关于IO (Input/Output)的概念,这里指程序运行时,数据在内存中由CPU 来快速的执行各种操作,数据在 内存、磁盘、网络等涉及数据交互的地方,都需要IO编程。数据编程分为同步IO和异步IO。

文件读写

文件操作是典型的IO操作,Python 中的读写操作与C是兼容的。并且我们要清楚读写文件是操作系统执行的,不是我们代码程序来执行的,我们的内置函数只是调用的操作系统的读写操作。

读文件

文件的读取有三个步骤:
1.打开文件 open()
2.读取数据 read() ,readline(),readlines
3.关闭数据 close()

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

try:
    # open 打开文件
    f = open('F:\python\HelloWord\example.log', 'r')
    print(f.read())
finally:
    if f:
        # close 关闭文件
        f.close()
        print('close....')
print('-----------------------')
with open('F:\python\HelloWord\example.log', 'r') as f:
    # read 读取所有数据
    print(f.read())
print('-----------------------')
with open('F:\python\HelloWord\example.log', 'r') as f:
    # read(size) 参数指 读取size个字节
    print(f.read(32))
    print(f.read(32))
print('-----------------------')
with open('F:\python\HelloWord\example.log', 'r') as f:
        # 读取文本的一行数据
        print( f.readline())
print('-----------------------')
with open('F:\python\HelloWord\example.log', 'r') as f:
    # 读取文本的全部数据,返回一个list,每行为一个元素
    for line in f.readlines():
        print(line.strip())  # 把末尾的'\n'删掉

输出结果:

ERROR:root:n = 0
ERROR:root:n = 0
ERROR:root:n = 1
close....
-----------------------
ERROR:root:n = 0
ERROR:root:n = 0
ERROR:root:n = 1
-----------------------
ERROR:root:n = 0
ERROR:root:n = 
0
ERROR:root:n = 1
-----------------------
ERROR:root:n = 0

-----------------------
ERROR:root:n = 0
ERROR:root:n = 0
ERROR:root:n = 1

首先文件读取完成后要关闭文件,来解除资源占用问题,所以我们要用try...finally...来包含代码块,在代码块出现错误异常时,也可以及时的关闭文件。python中的with语句可以代替这个操作,如上的代码;最后我们看读取文件的三种方式:read()一次性读取所有数据,当数据过大时,可以通过read(size) 来限制每次读取数据的大小,readline()按次序读取每行数据。 readlines() 读取所有数据返回每行的list。读取每行主要是获取配置文件的数据。

file-like Object

file-like Object 是典型的鸭子类型,open方法返回的是包括read()函数的对象,我们将包括read()对象的类统称为file-like Object,所以除了file之外,内存的字节流,网络流,自定义流只要有read()函数都可以成为file-like Object,而不用遵循继承规则。

二进制文件

read()函数读取的数据默认是 UTF-8格式的文本文件,如果要读取二进制文件应该通过 rb模式打开:
open('F:\python\HelloWord\example.log', 'rb')

字符编码

如果要读取非 UTF-8 格式的文本文件,我们需要在open()中传入编码格式,如 GBK编码:
open('F:\python\HelloWord\example.log', 'r', encoding='gbk')
对于不规范的编码文件,可以忽略掉:
open('F:\python\HelloWord\example.log', 'r', encoding='gbk', errors='ignore')

写文件

写数据与读数据相同:
1.打开文件 open()
2.读取数据 write()
3.关闭数据 close()

with open('F:\python\HelloWord\example.log', 'w') as f:
    f.write('hello word !')
    f.close()

with open('F:\python\HelloWord\example.log', 'a') as f:
    f.write('my name is zhangsan')
    f.close()

输出结果:

hello word !my name is zhangsan
close....
-----------------------
hello word !my name is zhangsan
-----------------------
hello word !my name is zhangsan

-----------------------
hello word !my name is zhangsan
-----------------------
hello word !my name is zhangsan

写文件只是将open()方法的参数改成w,w每次会覆盖原有的数据,a可以在原数据基础上追加。

内存中读写

内存中的读写 分为 StringIO、BytesIO,分别读写str,bytes。

StringIO 的读写

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from io import StringIO
# String IO 写入
f = StringIO()
f.write('hello')
f.write(' ')
f.write('world!')
print(f.getvalue())
print('---------------')
# String IO 读取
f = StringIO('Hello!\nHi!\nGoodbye!')
while True:
    s = f.readline()
    if s == '':
        break
    print(s.strip())

输出结果:

hello world!
---------------
Hello!
Hi!
Goodbye!

BytesIO 的读写

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from io import BytesIO
# BytesIO IO 写入
f = BytesIO()
f.write('中文'.encode('utf-8'))
print(f.getvalue())

# BytesIO IO 读取
f = BytesIO(b'\xe4\xb8\xad\xe6\x96\x87',)
print(f.read())

输出结果:

b'\xe4\xb8\xad\xe6\x96\x87'
b'\xe4\xb8\xad\xe6\x96\x87'

StringIO和BytesIO是在内存中操作str和bytes的方法。与读取文件的接口一致。

操作文件和目录

Python内置的os模块提供了可以直接调用操作系统提供的接口函数。让我们python 程序中可以调用系统的文件操作系统成为可能。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os

t = os.name # 操作系统类型
# 如果是posix,说明系统是Linux、Unix或Mac OS X,如果是nt,就是Windows系统
print(t) 

输出结果:

nt

说明是windows 系统。并且so 模块中的某些函数时针对操作系统的,有些操作系统,可能没有相对应的函数。

环境变量

python 可以通过os.environ可以获得系统的环境变量。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os

h = os.environ
print(h)

输出结果:

environ({'ALLUSERSPROFILE': 'C:\\ProgramData', 'ANDROID_HOME': 'D:\\WorkSoft\\Android\\sdk', 'APPDATA': 'C:\\Users\\Think\\AppData\\Roaming', 'CLASS_PATH': '.C:\\Program Files\\Java\\jdk1.8.0_60\\bin;C:\\Program Files\\Java\\jdk1.8.0_60\\lib\\tools.jar;', 'COMMONPROGRAMFILES': 'C:\\Program Files\\Common Files', 'COMMONPROGRAMFILES(X86)': 'C:\\Program Files (x86)\\Common Files', 'COMMONPROGRAMW6432': 'C:\\Program Files\\Common Files', 'COMMPATH': 'C:\\Program Files\\Lenovo\\Communications Utility', 'COMPUTERNAME': 'THINKPAD', 'COMSPEC': 'C:\\Windows\\system32\\cmd.exe', 'HOMEDRIVE': 'C:', 'HOMEPATH': '\\Users\\Think', 'JAVA_HOME': 'C:\\Program Files\\Java\\jdk1.8.0_60', 'LNKENV': 'D:\\系统软件\\360se6\\Application\\360se.exe', 'LOCALAPPDATA': 'C:\\Users\\Think\\AppData\\Local', 'LOGONSERVER': '\\\\THINKPAD', 'MAVEN_HOME': 'D:\\javadev\\apache-maven-3.3.9', 'NUMBER_OF_PROCESSORS': '8', 'OS': 'Windows_NT', 'PATH': 'C:\\ProgramData\\Oracle\\Java\\javapath;C:\\Windows\\system32;C:\\Windows;C:\\Windows\\System32\\Wbem;C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\;C:\\Program Files\\ThinkPad\\Bluetooth Software\\;C:\\Program Files\\ThinkPad\\Bluetooth Software\\syswow64;C:\\Windows\\system32\\config\\systemprofile\\.dnx\\bin;C:\\Program Files\\Microsoft DNX\\Dnvm\\;D:\\SVN\\TortoiseSVN\\bin;D:\\WorkSoft\\nodejs\\;D:\\WorkSoft\\Git\\cmd;C:\\Program Files (x86)\\Calibre2\\;D:\\Python\\Python36;D:\\VisualStudioCode\\Microsoft VS Code\\bin;C:\\Program Files\\Java\\jdk1.8.0_60\\bin;C:\\Program Files\\Java\\jdk1.8.0_60\\jre\\bin;C:\\ProgramData\\Oracle\\Java\\javapath;C:\\Windows\\system32;C:\\Windows;C:\\Windows\\System32\\Wbem;C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\;C:\\Program Files\\ThinkPad\\Bluetooth Software\\;C:\\Program Files\\ThinkPad\\Bluetooth Software\\syswow64;C:\\Windows\\system32\\config\\systemprofile\\.dnx\\bin;C:\\Program Files\\Microsoft DNX\\Dnvm\\;D:\\SVN\\TortoiseSVN\\bin;D:\\WorkSoft\\nodejs\\;D:\\WorkSoft\\Git\\cmd;C:\\Program Files (x86)\\Calibre2\\;D:\\Python\\Python36;D:\\WorkSoft\\Android\\sdk\\platform-tools;D:\\WorkSoft\\Android\\sdk\\tools;C:\\Users\\Think\\AppData\\Roaming\\npm;D:\\javadev\\apache-maven-3.3.9\\bin;F:\\python\\venv\\Scripts', 'PATHEXT': '.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC', 'PROCESSOR_ARCHITECTURE': 'AMD64', 'PROCESSOR_IDENTIFIER': 'Intel64 Family 6 Model 58 Stepping 9, GenuineIntel', 'PROCESSOR_LEVEL': '6', 'PROCESSOR_REVISION': '3a09', 'PROGRAMDATA': 'C:\\ProgramData', 'PROGRAMFILES': 'C:\\Program Files', 'PROGRAMFILES(X86)': 'C:\\Program Files (x86)', 'PROGRAMW6432': 'C:\\Program Files', 'PROMPT': '(venv) $P$G', 'PSMODULEPATH': 'C:\\Program Files\\WindowsPowerShell\\Modules;C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\Modules', 'PUBLIC': 'C:\\Users\\Public', 'PYCHARM_HOSTED': '1', 'PYCHARM_MATPLOTLIB_PORT': '57374', 'PYTHONIOENCODING': 'UTF-8', 'PYTHONPATH': 'D:\\WorkSoft\\python\\JetBrains\\PyCharm 2017.3.2\\helpers\\pycharm_matplotlib_backend;F:\\python', 'PYTHONUNBUFFERED': '1', 'SESSIONNAME': 'Console', 'SYSTEMDRIVE': 'C:', 'SYSTEMROOT': 'C:\\Windows', 'TEMP': 'C:\\Users\\Think\\AppData\\Local\\Temp', 'TFS_DIR': 'C:\\Program Files\\ThinkVantage Fingerprint Software\\', 'TMP': 'C:\\Users\\Think\\AppData\\Local\\Temp', 'USERDOMAIN': 'THINKPAD', 'USERDOMAIN_ROAMINGPROFILE': 'THINKPAD', 'USERNAME': 'Think', 'USERPROFILE': 'C:\\Users\\Think', 'VIRTUAL_ENV': 'F:\\python\\venv', 'VS140COMNTOOLS': 'D:\\工作软件\\Microsoft Visual Studio 14.0\\Common7\\Tools\\', 'WINDIR': 'C:\\Windows', '_OLD_VIRTUAL_PATH': 'C:\\ProgramData\\Oracle\\Java\\javapath;C:\\Windows\\system32;C:\\Windows;C:\\Windows\\System32\\Wbem;C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\;C:\\Program Files\\ThinkPad\\Bluetooth Software\\;C:\\Program Files\\ThinkPad\\Bluetooth Software\\syswow64;C:\\Windows\\system32\\config\\systemprofile\\.dnx\\bin;C:\\Program Files\\Microsoft DNX\\Dnvm\\;D:\\SVN\\TortoiseSVN\\bin;D:\\WorkSoft\\nodejs\\;D:\\WorkSoft\\Git\\cmd;C:\\Program Files (x86)\\Calibre2\\;D:\\Python\\Python36;D:\\VisualStudioCode\\Microsoft VS Code\\bin;C:\\Program Files\\Java\\jdk1.8.0_60\\bin;C:\\Program Files\\Java\\jdk1.8.0_60\\jre\\bin;C:\\ProgramData\\Oracle\\Java\\javapath;C:\\Windows\\system32;C:\\Windows;C:\\Windows\\System32\\Wbem;C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\;C:\\Program Files\\ThinkPad\\Bluetooth Software\\;C:\\Program Files\\ThinkPad\\Bluetooth Software\\syswow64;C:\\Windows\\system32\\config\\systemprofile\\.dnx\\bin;C:\\Program Files\\Microsoft DNX\\Dnvm\\;D:\\SVN\\TortoiseSVN\\bin;D:\\WorkSoft\\nodejs\\;D:\\WorkSoft\\Git\\cmd;C:\\Program Files (x86)\\Calibre2\\;D:\\Python\\Python36;D:\\WorkSoft\\Android\\sdk\\platform-tools;D:\\WorkSoft\\Android\\sdk\\tools;C:\\Users\\Think\\AppData\\Roaming\\npm;D:\\javadev\\apache-maven-3.3.9\\bin', '_OLD_VIRTUAL_PROMPT': '$P$G'})

如果我们要获取摸个环境变量的值可以通过`os.environ.get('key')

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os

v = os.environ.get('ANDROID_HOME')
print(v)

输出结果:

D:\WorkSoft\Android\sdk

操作文件和目录

python 中os.path模块中包含各种文件操作和目录的方法。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os

# 查看当前目录的绝对路径:
d =os.path.abspath('.')
print(d)
# 在某个目录下创建一个新目录,首先把新目录的完整路径表示出来:
os.path.join('/python/HelloWord', 'testdir')
# 然后创建一个目录:
os.mkdir('/python/HelloWord/testdir')
# 删掉一个目录:
os.rmdir('/python/HelloWord/testdir')
# 拆分目录
os.path.split('/python/HelloWord/file.txt')
# 拆分文件扩展名
os.path.splitext('/python/HelloWord/file.txt')
# 文件重命名
os.rename('file.txt', 'file1.txt')
# 输出当前文件夹下带有py后缀的文件名
s = [x for x in os.listdir('.') if os.path.isfile(x) and os.path.splitext(x)[1]=='.py']
print(s)

这样我们就可以查看目录,创建删除目录,和各种文件相关的操作,与java中的file方法相似。

序列化

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

  1. 序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上。
  2. 反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即unpickling。
import pickle

d = dict(name='Bob', age=20, score=88)
pickle.dumps(d)

f = open('dump.txt', 'wb')
pickle.dump(d, f)
f.close()

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

print(d)

输出结果:

{'name': 'Bob', 'age': 20, 'score': 88}

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

JSON

JSON 数据是现在网络传输、解析 最流行的数据接口,解析速度快,结构简单,Python也支持Json对象的相互转换。

import json

d = dict(name='Bob', age=20, score=88)
print(d)
# 将dict 转成json 格式
j = json.dumps(d)
print(j)
# json 反序列化
json_str = '{"name": "Bob", "age": 20, "score": 88}'
print(json.loads(json_str))

输出结果:

{'name': 'Bob', 'age': 20, 'score': 88}
{"name": "Bob", "age": 20, "score": 88}
{'name': 'Bob', 'age': 20, 'score': 88}

JSON 进阶

Json对象与类的实例相互转换

import json

class Student(object):
    def __init__(self, name, age, score):
        self.name = name
        self.age = age
        self.score = score
    # 自己写一个转dict 方法
    def student2dict(std):
        return {
            'name': std.name,
            'age': std.age,
            'score': std.score
        }


s = Student('Bob', 20, 88)
print(json.dumps(s.student2dict()))
# 直接通过 lambda 表达式在dumps 参数中转
print(json.dumps(s, default=lambda obj: obj.__dict__))

#json 解析
json_str = '{"name": "Bob", "age": 20, "score": 88}'
def dict2student(d):
    return Student(d['name'], d['age'], d['score'])
print(json.loads(json_str, object_hook=dict2student))
print(json.loads(json_str, object_hook=lambda d: Student(d['name'], d['age'], d['score'])))

输出结果:

{"name": "Bob", "age": 20, "score": 88}
{"name": "Bob", "age": 20, "score": 88}
Student object (Bob, 20, 88)
Student object (Bob, 20, 88)
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,179评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,229评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,032评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,533评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,531评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,539评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,916评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,813评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,568评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,654评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,354评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,937评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,918评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,152评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,852评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,378评论 2 342

推荐阅读更多精彩内容

  • Python 面向对象Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对...
    顺毛阅读 4,207评论 4 16
  • IO编程概念 IO在计算机中指Input/Output,也就是输入和输出。由于程序和运行时数据是在内存中驻留,由C...
    时间之友阅读 720评论 0 0
  • pyton review 学习指南 https://www.zhihu.com/question/29138020...
    孙小二wuk阅读 1,039评论 0 2
  • # Python 资源大全中文版 我想很多程序员应该记得 GitHub 上有一个 Awesome - XXX 系列...
    aimaile阅读 26,436评论 6 428
  • 芳草地一夜醒来荒草地 歌中的驼铃 梦中的夜莺 情人的眼睛 丢过手绢摘过星 有去无回 淤了满脚青 2015.4.5
    白辣阅读 265评论 0 1