学习廖老师的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
>>> 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 是 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>