Day-11: IO編程

  因爲CUP的運行速度遠高於其餘外設,IO操做有兩種方式:python

  同步IO:CUP登着,程序暫停直到執行完後續代碼編程

  異步IO:CUP不等待,去作其餘的事情,磁盤作完該作的事情後,告訴CUP,CUP再進行後續代碼json

  異步IO操做較爲複雜,這裏記錄同步IO操做。網絡

  • 文件讀寫

  Python中讀寫文件是經過由操做系統提供的。異步

  讀文件:先使用open()方法打開文件,以後使用read()方法讀入內存。編程語言

>>> f = open('/Users/michael/test.txt', 'r')
>>> f.read()
'Hello, world!'

  最後,必須close()關閉文件,由於文件對象會佔用操做系統的資源。學習

>>> f.close()

  而在其中一旦出了錯誤,就會拋出IOError,爲了保證最後能close(),使用with語句,來代替測試

with open('/path/to/file', 'r') as f:
    print f.read()

  其中,read()一次性讀取所有內容,read(size),每次讀取size個字節的內容,readline()每次讀取一行內容,readlines()一次讀取全部內容,每一行都儲存在list的一個元素中。編碼

對於readlines()可使用:spa

for line in f.readlines():
    print(line.strip()) # 把末尾的'\n'刪掉

  凡是可使用open()打開的對象,都是file-like Object。除了file外,還有內存的字節流,網絡流,自定義流等。

  普通的文件是以ASCII碼編寫的,而對於圖片,視頻等是由二進制文件編寫的,得用‘rb’模式打開。

  對於非ASCII編碼的文件,必須得由二進制模式打開,再解碼。好比GBK編碼的文件:

>>> f = open('/Users/michael/gbk.txt', 'rb')
>>> u = f.read().decode('gbk')
>>> u
u'\u6d4b\u8bd5'
>>> print u
測試

這裏有簡化的方法,利用codecs模塊,自動轉碼

import codecs
with codecs.open('/Users/michael/gbk.txt', 'r', 'gbk') as f:
    f.read() # u'\u6d4b\u8bd5'

  寫文件:寫文件與讀文件相似,爲確保數據所有由內存寫入文件,使用with語句

with open('/Users/michael/test.txt', 'w') as f:
    f.write('Hello, world!')

若有特定編碼的文本文件,使用codecs模塊。

  • 操做文件和目錄

   獲取環境變量:os.environ

  獲取某個環境變量的值:os.getenv(‘PATH’)

  查看當前目錄的據對路徑:os.path.abspath('.')

  將兩個路徑拼成一個:os.path.join('/User/michael', 'testdir')

  建立一個目錄:os.mkdir('/Users/michael/testdir')

  刪除一個目錄:os.rmdir('/Users/michael/testdir')

  拆分路徑,獲得最後一級的文件或目錄名:os.path.split('/Users/michael/testdir/file.txt')

  拆分路徑,獲得文件擴展名:os.path.splitext('/path/to/file.txt')

  文件重命名:os.rename('test.txt', 'test.py')

  刪掉文件:os.remove('test.py')

  複製文件:在shutil模塊中的copyfile()

  列出當前目錄下的全部目錄:[x for x in os.listdir('.') if os.path.isdir(x)]

  列出全部的.py文件:[x for x in os.listdir('.') if os.path.isfile(x) and os.path.splitext(x)[1]=='.py']

  • 序列化

  變量從內存中變成可儲存或傳輸的過程稱爲序列化,Python中負責序列化的叫作pickle和cPickle。

  pickle和cPickle的區別在於cPickle是用c寫的,速度快;pickle是用python寫的,速度慢。因此:

try:
    import cPickle as pickle
except ImportError:
    import pickle

  將對象序列化並寫入文件:

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

  將對象從磁盤讀到內存,反序列化:

>>> f = open('dump.txt', 'rb')
>>> d = pickle.load(f)
>>> f.close()
>>> d
{'age': 20, 'score': 88, 'name': 'Bob'}

  pickle序列化對象後,存儲的變量和原來的變量徹底不同,知識內容相同,並且每一個語言序列化後的變量也是不同的。爲了在不一樣的編程語言間傳遞對象,必須把對象序列化爲標準格式。Python內置的json模塊提供了很是完善的Python對象到JSON格式的轉換。

{} dict
[] list
"string" 'str'或u'unicode'
1234.56 int或float
true/false True/False
null None

使用json.dump方法

>>> import json
>>> d = dict(name='Bob', age=20, score=88)
>>> json.dumps(d)
'{"age": 20, "score": 88, "name": "Bob"}'

相似的,dump()方法能夠直接把JSON寫入一個file-like Object

JSON反序列化

>>> json_str = '{"age": 20, "score": 88, "name": "Bob"}'
>>> json.loads(json_str)
{u'age': 20, u'score': 88, u'name': u'Bob'}

loads()把JSON的字符串反序列化,load()從file-like Object中讀取字符串並序列化

將Student實例變成一個JSON對象。

def student2dict(std):
    return {
        'name': std.name,
        'age': std.age,
        'score': std.score
    }

print(json.dumps(s, default=student2dict))

將JSON反序列化爲一個Student對象實例

def dict2student(d):
    return Student(d['name'], d['age'], d['score'])

json_str = '{"age": 20, "score": 88, "name": "Bob"}'
print(json.loads(json_str, object_hook=dict2student))

  注:本文爲學習廖雪峯Python入門整理後的筆記

相關文章
相關標籤/搜索