本系列主要学习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等等,都是一个意思。
- 序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上。
- 反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即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)