Python學(xué)習(xí)10-IO編程2

StringIO和BytesIO

很多時(shí)候咸作,數(shù)據(jù)讀寫不一定是文件浙值,也可以在內(nèi)存中讀寫羔巢。
StringIO顧名思義就是在內(nèi)存中讀寫str。
要把str寫入StringIO吴叶,我們需要先創(chuàng)建一個(gè)StringIO阐虚,然后,像文件一樣寫入即可:

>>> from io import StringIO
>>> f = StringIO()
>>> f.write('hello')
5
>>> f.write(' ')
1
>>> f.write('world!')
6
>>> print(f.getvalue())
hello world!

getvalue()方法用于獲得寫入后的str蚌卤。
要讀取StringIO实束,可以用一個(gè)str初始化StringIO奥秆,然后,像讀文件一樣讀认滩印:

>>> from io import StringIO
>>> f = StringIO('Hello!\nHi!\nGoodbye!')
>>> while True:
...     s = f.readline()
...     if s == '':
...         break
...     print(s.strip())
...
Hello!
Hi!
Goodbye!
  • BytesIO
    StringIO操作的只能是str构订,如果要操作二進(jìn)制數(shù)據(jù),就需要使用BytesIO避矢。
    BytesIO實(shí)現(xiàn)了在內(nèi)存中讀寫bytes悼瘾,我們創(chuàng)建一個(gè)BytesIO,然后寫入一些bytes:
>>> from io import BytesIO
>>> f = BytesIO()
>>> f.write('中文'.encode('utf-8'))
6
>>> print(f.getvalue())
b'\xe4\xb8\xad\xe6\x96\x87'

請注意审胸,寫入的不是str亥宿,而是經(jīng)過UTF-8編碼的bytes。
和StringIO類似砂沛,可以用一個(gè)bytes初始化BytesIO烫扼,然后,像讀文件一樣讀劝帧:

>>> from io import BytesIO
>>> f = BytesIO(b'\xe4\xb8\xad\xe6\x96\x87')
>>> f.read()
b'\xe4\xb8\xad\xe6\x96\x87'

操作文件和目錄

如果我們要操作文件映企、目錄,可以在命令行下面輸入操作系統(tǒng)提供的各種命令來完成静浴。比如dir堰氓、cp等命令。

如果要在Python程序中執(zhí)行這些目錄和文件的操作怎么辦马绝?其實(shí)操作系統(tǒng)提供的命令只是簡單地調(diào)用了操作系統(tǒng)提供的接口函數(shù)豆赏,Python內(nèi)置的os模塊也可以直接調(diào)用操作系統(tǒng)提供的接口函數(shù)。

打開Python交互式命令行富稻,我們來看看如何使用os模塊的基本功能:

>>> import os
>>> os.name # 操作系統(tǒng)類型
'posix'

如果是posix,說明系統(tǒng)是Linux白胀、Unix或Mac OS X椭赋,如果是nt,就是Windows系統(tǒng)或杠。

要獲取詳細(xì)的系統(tǒng)信息哪怔,可以調(diào)用uname()函數(shù):

>>> os.uname()
posix.uname_result(sysname='Darwin', nodename='MichaelMacPro.local', release='14.3.0', version='Darwin Kernel Version 14.3.0: Mon Mar 23 11:59:05 PDT 2015; root:xnu-2782.20.48~5/RELEASE_X86_64', machine='x86_64')

注意uname()函數(shù)在Windows上不提供,也就是說向抢,os模塊的某些函數(shù)是跟操作系統(tǒng)相關(guān)的认境。

  • 環(huán)境變量
    在操作系統(tǒng)中定義的環(huán)境變量,全部保存在os.environ這個(gè)變量中挟鸠,可以直接查看:
>>> os.environ
environ({'VERSIONER_PYTHON_PREFER_32_BIT': 'no', 'TERM_PROGRAM_VERSION': '326', 'LOGNAME': 'michael', 'USER': 'michael', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/X11/bin:/usr/local/mysql/bin', ...})

要獲取某個(gè)環(huán)境變量的值叉信,可以調(diào)用os.environ.get('key'):

>>> os.environ.get('PATH')
'/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/X11/bin:/usr/local/mysql/bin'
>>> os.environ.get('x', 'default')
'default'
  • 操作文件和目錄

操作文件和目錄的函數(shù)一部分放在os模塊中,一部分放在os.path模塊中艘希,這一點(diǎn)要注意一下硼身。查看硅急、創(chuàng)建和刪除目錄可以這么調(diào)用:

# 查看當(dāng)前目錄的絕對路徑:
>>> os.path.abspath('.')
'/Users/michael'
# 在某個(gè)目錄下創(chuàng)建一個(gè)新目錄,首先把新目錄的完整路徑表示出來:
>>> os.path.join('/Users/michael', 'testdir')
'/Users/michael/testdir'
# 然后創(chuàng)建一個(gè)目錄:
>>> os.mkdir('/Users/michael/testdir')
# 刪掉一個(gè)目錄:
>>> os.rmdir('/Users/michael/testdir')

把兩個(gè)路徑合成一個(gè)時(shí)佳遂,不要直接拼字符串营袜,而要通過os.path.join()函數(shù),這樣可以正確處理不同操作系統(tǒng)的路徑分隔符丑罪。在Linux/Unix/Mac下荚板,os.path.join()返回這樣的字符串:

part-1/part-2
而Windows下會返回這樣的字符串:

part-1\part-2
同樣的道理,要拆分路徑時(shí)吩屹,也不要直接去拆字符串跪另,而要通過os.path.split()函數(shù),這樣可以把一個(gè)路徑拆分為兩部分祟峦,后一部分總是最后級別的目錄或文件名:

>>> os.path.split('/Users/michael/testdir/file.txt')
('/Users/michael/testdir', 'file.txt')

os.path.splitext()可以直接讓你得到文件擴(kuò)展名罚斗,很多時(shí)候非常方便:

>>> os.path.splitext('/path/to/file.txt')
('/path/to/file', '.txt')

這些合并、拆分路徑的函數(shù)并不要求目錄和文件要真實(shí)存在宅楞,它們只對字符串進(jìn)行操作针姿。

文件操作使用下面的函數(shù)。假定當(dāng)前目錄下有一個(gè)test.txt文件:

# 對文件重命名:
>>> os.rename('test.txt', 'test.py')
# 刪掉文件:
>>> os.remove('test.py')

但是復(fù)制文件的函數(shù)居然在os模塊中不存在厌衙!原因是復(fù)制文件并非由操作系統(tǒng)提供的系統(tǒng)調(diào)用距淫。理論上講,我們通過上一節(jié)的讀寫文件可以完成文件復(fù)制婶希,只不過要多寫很多代碼榕暇。

幸運(yùn)的是shutil模塊提供了copyfile()的函數(shù),你還可以在shutil模塊中找到很多實(shí)用函數(shù)喻杈,它們可以看做是os模塊的補(bǔ)充彤枢。

最后看看如何利用Python的特性來過濾文件。比如我們要列出當(dāng)前目錄下的所有目錄筒饰,只需要一行代碼:

>>> [x for x in os.listdir('.') if os.path.isdir(x)]
['.lein', '.local', '.m2', '.npm', '.ssh', '.Trash', '.vim', 'Applications', 'Desktop', ...]

要列出所有的.py文件缴啡,也只需一行代碼:

>>> [x for x in os.listdir('.') if os.path.isfile(x) and os.path.splitext(x)[1]=='.py']
['apis.py', 'config.py', 'models.py', 'pymonitor.py', 'test_db.py', 'urls.py', 'wsgiapp.py']

小結(jié)
Python的os模塊封裝了操作系統(tǒng)的目錄和文件操作,要注意這些函數(shù)有的在os模塊中瓷们,有的在os.path模塊中业栅。

練習(xí)
1.利用os模塊編寫一個(gè)能實(shí)現(xiàn)dir -l輸出的程序。
在我的Mac上dir -l等同于ls -l,以下是顯示效果:


Screen Shot 2018-05-28 at 3.21.42 PM.png

這里就寫一個(gè)簡化的谬晕,前面幾項(xiàng)權(quán)限碘裕、hard link數(shù)目等等就省了:

import os
import time

for file in os.listdir('.'):
    fileSize = os.path.getsize(file)
    rawTime = os.path.getmtime(file)
    mTime = time.localtime(rawTime)
    modifyTime = time.strftime('%Y-%m-%d %H:%M', mTime)
    fileName = file
    print("%d  %s  %s" % (fileSize, modifyTime, fileName))


效果:


Screen Shot 2018-05-28 at 3.58.48 PM.png

2.編寫一個(gè)程序,能在當(dāng)前目錄以及當(dāng)前目錄的所有子目錄下查找文件名包含指定字符串的文件攒钳,并打印出相對路徑帮孔。

import os
import time

# 獲取當(dāng)前目錄路徑
cwd = os.getcwd()

def search_file(name):
    file_list = [x for x in os.listdir(cwd) if os.path.isfile(x)]
    for file in file_list:
        if name in file.split('.')[0]:
            print(os.path.abspath(file))        

def search(name):
    search_file(name)
    dir_list = [x for x in os.listdir() if os.path.isdir(x)]
    for d in dir_list:
        os.chdir(d)
        search(name)
        os.chdir('..')

name = input("Please enter the file name:\n")
search(name)

效果:


Screen Shot 2018-05-28 at 5.08.09 PM.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市夕玩,隨后出現(xiàn)的幾起案子你弦,更是在濱河造成了極大的恐慌惊豺,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件禽作,死亡現(xiàn)場離奇詭異尸昧,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)旷偿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進(jìn)店門烹俗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人萍程,你說我怎么就攤上這事幢妄。” “怎么了茫负?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵蕉鸳,是天一觀的道長。 經(jīng)常有香客問我忍法,道長潮尝,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任饿序,我火速辦了婚禮勉失,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘原探。我一直安慰自己乱凿,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布咽弦。 她就那樣靜靜地躺著徒蟆,像睡著了一般。 火紅的嫁衣襯著肌膚如雪型型。 梳的紋絲不亂的頭發(fā)上后专,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天,我揣著相機(jī)與錄音输莺,去河邊找鬼。 笑死裸诽,一個(gè)胖子當(dāng)著我的面吹牛嫂用,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播丈冬,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼嘱函,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了埂蕊?” 一聲冷哼從身側(cè)響起往弓,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤疏唾,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后函似,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體槐脏,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年撇寞,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了顿天。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,664評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蔑担,死狀恐怖牌废,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情啤握,我是刑警寧澤鸟缕,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站排抬,受9級特大地震影響懂从,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜畜埋,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一莫绣、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧悠鞍,春花似錦对室、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至么翰,卻和暖如春牺汤,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背浩嫌。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工檐迟, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人码耐。 一個(gè)月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓追迟,卻偏偏與公主長得像,于是被迫代替她去往敵國和親骚腥。 傳聞我的和親對象是個(gè)殘疾皇子敦间,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評論 2 359

推薦閱讀更多精彩內(nèi)容