IO编程
文件读写
在磁盘上读写文件的功能都是由操作系统提供的,现在操作系统不允许程序直接读取磁盘,所以读写文件就是请求操作系统打开一个文件对象,然后通过操作系统提供的这个接口从这个文件对象中读写文件
文件使用完毕后必须关闭,因为文件对象会占用操作系统的资源
由于文件读写时可能会产生IOError,一旦出错,f.close()就不会执行。所以我们用try,finally
try:
f = open('file', 'r')
print(f.read())
finally:
if f:
f.close()
但是每次这么写很费事,python给我们提供了with语句
with open('file', 'r') as f:
print(f.read())
with语句的功能和try…finally的功能是一样的,但是不用写f.close()
for line in f.readlines():
print(line.strip())
要读取二进制文件,如图片视频等
f = open('file', 'rb')
- 要读取非utf-8编码的文本文件,需要给open函数传入encoding参数
- 如果遇到编码不规范的文件,可能会遇到UnicodeDecodeError,可以在open函数中传入errors参数,表示如果遇到编码错误则忽略
f.open('gbk_file', 'r', encoding='gbk', errors='ignore')
写文件也同样如此
with open('file', 'w') as f:
f.write()
要写入特定编码的文本文件,需要给open函数传入encoding参数,将字符串自动转换成指定编码
StringIO和BytesIO
很多时候,数据读写也不一定是文件,也可以再内存中读写
StringIO就是在内存中读写数据
from io import StringIO
f = StringIO()
f.write('hello world')
11
f.getvalue()
'hello world'
如果要操作二进制数据,则要用BytesIO
from io import BytesIO
f = BytesIO()
f.write('中文'.encode('utf-8')) #写入的是经过utf-8编码的bytes
f.getvalue()
b'\xe4\xb8\xad\xe6\x96\x87'
操作文件和目录
python 内置的os模块可以直接调用操作系统提供的接口函数
import os
print(os.name) #操作系统类型 nt是window,posix是linux系统
nt
os.environ
environ({'PROGRAMFILES': 'C:\\Program Files', 'USERDOMAIN': 'DESKTOP-H547PQ0', 'FPS_BROWSER_USER_PROFILE_STRING': 'Default', 'PAGER': 'cat', 'USERPROFILE': 'C:\\Users\\lovelyfrog', 'CHOCOLATEYINSTALL': 'C:\\ProgramData\\chocolatey', 'HOMEDRIVE': 'C:', 'PATH': 'C:\\ProgramData\\Oracle\\Java\\javapath;C:\\Program Files\\PHP\\v7.0;C:\\Python27\\;C:\\Python27\\Scripts;C:\\Users\\lovelyfrog\\Python27\\;C:\\Users\\lovelyfrog\\Python27\\Scripts;C:\\WINDOWS\\system32;C:\\WINDOWS;C:\\WINDOWS\\System32\\Wbem;C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\;C:\\Program Files\\Redis\\;C:\\ProgramData\\chocolatey\\bin;C:\\ProgramData\\chocolatey\\lib\\msys2;C:\\Program Files\\Git\\cmd;C:\\Program Files\\nodejs\\;C:\\WINDOWS\\system32\\config\\systemprofile\\AppData\\Local\\Microsoft\\WindowsApps;C:\\Users\\lovelyfrog\\AppData\\Local\\Programs\\Python\\Python35\\Scripts\\;C:\\Users\\lovelyfrog\\AppData\\Local\\Programs\\Python\\Python35\\;C:\\Users\\lovelyfrog\\AppData\\Local\\Microsoft\\WindowsApps;C:\\Users\\lovelyfrog\\Documents\\机器学习实战;C:\\Users\\lovelyfrog\\Documents\\python crawler\\phantomjs-2.1.1-windows\\bin\\;C:\\tools\\msys64;C:\\Users\\lovelyfrog\\AppData\\Roaming\\npm;D:\\biomechanics\\code;D:\\amp\\php;C:\\Users\\lovelyfrog\\AppData\\Local\\Programs\\Python\\Python35\\Scripts\\;C:\\Users\\lovelyfrog\\AppData\\Local\\Programs\\Python\\Python35\\;C:\\Users\\lovelyfrog\\AppData\\Local\\Microsoft\\WindowsApps;C:\\Users\\lovelyfrog\\Documents\\机器学习实战;C:\\Users\\lovelyfrog\\Documents\\python crawler\\phantomjs-2.1.1-windows\\bin\\;C:\\ProgramData\\chocolatey\\lib\\msys2;C:\\tools\\msys64;C:\\Users\\lovelyfrog\\AppData\\Roaming\\npm;D:\\biomechanics\\code;', 'OS': 'Windows_NT', 'PROGRAMFILES(X86)': 'C:\\Program Files (x86)', 'COMPUTERNAME': 'DESKTOP-H547PQ0', 'CHOCOLATEYTOOLSLOCATION': 'C:\\tools', 'PROCESSOR_REVISION': '3d04', 'CLICOLOR': '1', 'PSMODULEPATH': 'C:\\Program Files\\WindowsPowerShell\\Modules;C:\\WINDOWS\\system32\\WindowsPowerShell\\v1.0\\Modules', 'JPY_PARENT_PID': '1276', 'MOZ_PLUGIN_PATH': 'C:\\Program Files (x86)\\Foxit Software\\Foxit Reader\\plugins\\', 'TEMP': 'C:\\Users\\LOVELY~1\\AppData\\Local\\Temp', 'MPLBACKEND': 'module://ipykernel.pylab.backend_inline', 'USERNAME': 'lovelyfrog', 'PROGRAMW6432': 'C:\\Program Files', 'PROCESSOR_ARCHITECTURE': 'AMD64', 'PUBLIC': 'C:\\Users\\Public', 'TMP': 'C:\\Users\\LOVELY~1\\AppData\\Local\\Temp', 'ALLUSERSPROFILE': 'C:\\ProgramData', 'PROCESSOR_IDENTIFIER': 'Intel64 Family 6 Model 61 Stepping 4, GenuineIntel', 'SYSTEMROOT': 'C:\\WINDOWS', 'COMSPEC': 'C:\\WINDOWS\\system32\\cmd.exe', 'HOMEPATH': '\\Users\\lovelyfrog', 'COMMONPROGRAMFILES': 'C:\\Program Files\\Common Files', 'PROMPT': '$P$G', 'JPY_INTERRUPT_EVENT': '1272', 'WINDIR': 'C:\\WINDOWS', 'NUMBER_OF_PROCESSORS': '4', 'LOCALAPPDATA': 'C:\\Users\\lovelyfrog\\AppData\\Local', 'TERM': 'xterm-color', 'LOGONSERVER': '\\\\DESKTOP-H547PQ0', 'PATHEXT': '.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC', 'PROCESSOR_LEVEL': '6', 'ONEDRIVE': 'C:\\Users\\lovelyfrog\\OneDrive', 'COMMONPROGRAMW6432': 'C:\\Program Files\\Common Files', 'USERDOMAIN_ROAMINGPROFILE': 'DESKTOP-H547PQ0', 'GIT_PAGER': 'cat', 'SYSTEMDRIVE': 'C:', 'CHOCOLATEYLASTPATHUPDATE': '周四 7月 20 13:52:42 2017', 'APPDATA': 'C:\\Users\\lovelyfrog\\AppData\\Roaming', 'PROGRAMDATA': 'C:\\ProgramData', 'IPY_INTERRUPT_EVENT': '1272', 'SESSIONNAME': 'Console', 'FPS_BROWSER_APP_PROFILE_STRING': 'Internet Explorer', 'VS140COMNTOOLS': 'C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\Common7\\Tools\\', 'COMMONPROGRAMFILES(X86)': 'C:\\Program Files (x86)\\Common Files'})
os.environ.get('PATH')
'C:\\ProgramData\\Oracle\\Java\\javapath;C:\\Program Files\\PHP\\v7.0;C:\\Python27\\;C:\\Python27\\Scripts;C:\\Users\\lovelyfrog\\Python27\\;C:\\Users\\lovelyfrog\\Python27\\Scripts;C:\\WINDOWS\\system32;C:\\WINDOWS;C:\\WINDOWS\\System32\\Wbem;C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\;C:\\Program Files\\Redis\\;C:\\ProgramData\\chocolatey\\bin;C:\\ProgramData\\chocolatey\\lib\\msys2;C:\\Program Files\\Git\\cmd;C:\\Program Files\\nodejs\\;C:\\WINDOWS\\system32\\config\\systemprofile\\AppData\\Local\\Microsoft\\WindowsApps;C:\\Users\\lovelyfrog\\AppData\\Local\\Programs\\Python\\Python35\\Scripts\\;C:\\Users\\lovelyfrog\\AppData\\Local\\Programs\\Python\\Python35\\;C:\\Users\\lovelyfrog\\AppData\\Local\\Microsoft\\WindowsApps;C:\\Users\\lovelyfrog\\Documents\\机器学习实战;C:\\Users\\lovelyfrog\\Documents\\python crawler\\phantomjs-2.1.1-windows\\bin\\;C:\\tools\\msys64;C:\\Users\\lovelyfrog\\AppData\\Roaming\\npm;D:\\biomechanics\\code;D:\\amp\\php;C:\\Users\\lovelyfrog\\AppData\\Local\\Programs\\Python\\Python35\\Scripts\\;C:\\Users\\lovelyfrog\\AppData\\Local\\Programs\\Python\\Python35\\;C:\\Users\\lovelyfrog\\AppData\\Local\\Microsoft\\WindowsApps;C:\\Users\\lovelyfrog\\Documents\\机器学习实战;C:\\Users\\lovelyfrog\\Documents\\python crawler\\phantomjs-2.1.1-windows\\bin\\;C:\\ProgramData\\chocolatey\\lib\\msys2;C:\\tools\\msys64;C:\\Users\\lovelyfrog\\AppData\\Roaming\\npm;D:\\biomechanics\\code;'
操作文件和目录
#查看当前目录
os.path.abspath('.')
'D:\\python_project\\some_thought'
把两个路径合成一个时,不要直接拼接字符串,而要用os.path.join(),这样可以正确处理不同操作系统的分隔符,同理拆分路径时要用os.path.split()
os.path.join('D:\python','sss')
'D:\\python\\sss'
os.path.split('D:\python_project\cat.jpg')
('D:\\python_project', 'cat.jpg')
os.path.splitext('D:\python_project\cat.jpg') #有时会非常方便
('D:\\python_project\\cat', '.jpg')
#文件操作
os.rename('test.txt','test.py')
os.remove('test.py')
但是复制文件的函数在os中是不存在的,幸运的是shutil模块提供了copyfile()函数,shutil模块可以看作是os的补充
利用python的一些特性来过滤文件
[x for x in os.listdir('.') if os.path.isdir(x)] #获取当前目录下所有文件夹
['.idea', '.ipynb_checkpoints', 'ItChat-master']
[x for x in os.listdir('.') if os.path.isfile(x) and os.path.splitext(x)[1]=='.py']
['custom_made_class.py']
序列化
我们把变量从内存中编程可存储或者可传输的过程就叫做序列化,在python中叫pickling.序列化后就可以将序列化后的内容写入磁盘或者传输到网上
import pickle
d = dict(name='lovelyfrog', age=20, score=90)
pickle.dumps(d)
b'\x80\x03}q\x00(X\x05\x00\x00\x00scoreq\x01KZX\x04\x00\x00\x00nameq\x02X\n\x00\x00\x00lovelyfrogq\x03X\x03\x00\x00\x00ageq\x04K\x14u.'
f = open('dump.txt','wb')
pickle.dump(d, f)
f.close()
f = open('dump.txt', 'rb')
d = pickle.load(f)
d
{'age': 20, 'name': 'lovelyfrog', 'score': 90}
pickle只适用于python
JSON
如果在不同编程语言中传递对象,就必须把对象序列化为标准格式,最好的方法是序列成JSON,JSON表示的对象就是标准的JavaScript语言的对象
python内置的json模块提供了非常完善的从python对象到JSON格式的转换,类似的dump()可以将JSON写入一个file-like-object中
从JSON反序列化,可以用loads(),或者load()从一个file-like object中读取字符串并反序列化
import json
d = dict(name='lovelyfrog', age=20, score=90)
json.dumps(d)
'{"score": 90, "name": "lovelyfrog", "age": 20}'
json_str = json.dumps(d)
json.loads(json_str)
{'age': 20, 'name': 'lovelyfrog', 'score': 90}
json_str['name']
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-37-c351198a8340> in <module>()
----> 1 json_str['name']
TypeError: string indices must be integers
类对象不是一个可以json序列化的对象,但是我们可以更改default参数,为类写一个转换函数
class Student(object):
def __init__(self,name,age,score):
self.name=name
self.age=age
self.score=score
s = Student('lovelyfrog',20,90)
json.dumps(s)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-33-2531144bea7e> in <module>()
----> 1 json.dumps(s)
~\AppData\Local\Programs\Python\Python35\lib\json\__init__.py in dumps(obj, skipkeys, ensure_ascii, check_circular, allow_nan, cls, indent, separators, default, sort_keys, **kw)
228 cls is None and indent is None and separators is None and
229 default is None and not sort_keys and not kw):
--> 230 return _default_encoder.encode(obj)
231 if cls is None:
232 cls = JSONEncoder
~\AppData\Local\Programs\Python\Python35\lib\json\encoder.py in encode(self, o)
196 # exceptions aren't as detailed. The list call should be roughly
197 # equivalent to the PySequence_Fast that ''.join() would do.
--> 198 chunks = self.iterencode(o, _one_shot=True)
199 if not isinstance(chunks, (list, tuple)):
200 chunks = list(chunks)
~\AppData\Local\Programs\Python\Python35\lib\json\encoder.py in iterencode(self, o, _one_shot)
254 self.key_separator, self.item_separator, self.sort_keys,
255 self.skipkeys, _one_shot)
--> 256 return _iterencode(o, 0)
257
258 def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
~\AppData\Local\Programs\Python\Python35\lib\json\encoder.py in default(self, o)
177
178 """
--> 179 raise TypeError(repr(o) + " is not JSON serializable")
180
181 def encode(self, o):
TypeError: <__main__.Student object at 0x000001BE15084518> is not JSON serializable
同样的道理,如果我们要把JSON反序列化为一个Student对象实例,loads()方法首先转换出一个dict对象,然后,我们传入的object_hook函数负责把dict转换为Student实例
def student2dict(std):
return {
'name':std.name,
'age':std.age,
'score':std.score
}
print(json.dumps(s, default=student2dict))
{"score": 90, "name": "lovelyfrog", "age": 20}
通常class都有一个dict属性用来储存实例变量,
print(json.dumps(s.__dict__))
{"score": 90, "age": 20, "name": "lovelyfrog"}
def dict2student(d):
return Student(d['name'], d['age'], d['score'])
print(json.loads(json_str, object_hook=dict2student))
<__main__.Student object at 0x000001BE1510A198>