python基礎(chǔ)8-文件和異常

8.1屋彪、從文件中讀取數(shù)據(jù)

要使用文本文件中的信息所宰,首先需要將信息讀取到內(nèi)存中,為此畜挥,可以選擇一次行讀取文件的全部?jī)?nèi)容仔粥,也可以以每次一行的方式逐步讀取。

8.1.1蟹但、讀取整個(gè)文件

要以任何方式使用文件躯泰,都要先打開文,這樣才能訪問(wèn)华糖。

open()接受一個(gè)參數(shù)麦向,表示要打開文件的文件名

with在不再需要訪問(wèn)文件后將其關(guān)閉

在這個(gè)例子中,沒(méi)有使用close()來(lái)關(guān)閉文件客叉,但是可以調(diào)用open()和close()來(lái)打開和關(guān)閉文件诵竭,但是如果這樣做的話,如果程序存在bug兼搏,導(dǎo)致close()語(yǔ)句未執(zhí)行秀撇,文件將不會(huì)關(guān)閉,未妥善關(guān)閉文件會(huì)導(dǎo)致數(shù)據(jù)丟失或受損向族。

通過(guò)這種結(jié)構(gòu),可以讓Python去決定什么時(shí)候講文件關(guān)閉

with open('pi_digits.txt') as file_object:
    contents = file_object.read()
    print(contents)

輸出結(jié)果會(huì)多一個(gè)空行棠绘,因?yàn)閞ead()到達(dá)文件末尾時(shí)返回一個(gè)空字符串件相,而將這個(gè)空字符串顯示出來(lái)時(shí)就是一個(gè)空行,可以在print語(yǔ)句中使用rstrip()來(lái)消除空行

8.1.2氧苍、文件路徑

python只會(huì)在文件夾中找夜矗,而不會(huì)在其子文件夾中查找,因此要讓python打開不與程序文件位于同一個(gè)目錄中的文件让虐,需要提供文件路徑紊撕。

  • linux中使用斜杠/
  • windows中使用反斜杠\

8.1.3、逐行讀取

讀取文件是赡突,常常需要檢查其中的每一行:你可能要在文件中查找特定的信息对扶,或者要以某種方式修改文件中的文本区赵。

每行的末尾都有一個(gè)看不見的換行符,而print語(yǔ)句也會(huì)加上一個(gè)換行符浪南,因此每行末尾都有兩個(gè)換行符笼才,可在Print語(yǔ)句中使用rstrip()函數(shù)來(lái)消除換行符

filename = 'pi_digits.txt'

with open(filename) as file_object:
    for line in file_object:
        print(line)

8.1.4、創(chuàng)建一個(gè)包含文件各行內(nèi)容的列表

使用關(guān)鍵字with是络凿,open()返回的文件對(duì)象只能在with代碼塊中使用骡送。如果要在with代碼外訪問(wèn)文件的內(nèi)容,可在with代碼塊內(nèi)將文件的各行存儲(chǔ)在一個(gè)列表中絮记,并在with代碼塊外使用該列表

ef read_file_on_line(filename):
    with open(filename) as file_object:
        lines = file_object.readlines()

    for line in lines:
        print(line.rstrip())


filename = 'pi_digits.txt'
read_file_on_line(filename)

8.1.5摔踱、使用文件的內(nèi)容

將文件讀取到內(nèi)存中后,就可以以任何方式使用這些數(shù)據(jù)了怨愤。

python將文本內(nèi)容都解讀為字符串派敷,如果讀取的是數(shù)字,需要使用int()或者float()函數(shù)將其轉(zhuǎn)換為浮點(diǎn)數(shù)

filename = 'pi_digits.txt'

with open(filename) as file_object:
    lines = file_object.readlines()

pi_string = ""
for line in lines:
    pi_string += line.rstrip()

print(pi_string)
print(len(pi_string))

8.1.6憔四、包含一百萬(wàn)位的大型文件

在文件中有大量數(shù)據(jù)時(shí)膀息,可以使用列表截取的方式來(lái)讀取隨機(jī)位置的有限位文本

filename = 'pi_digits.txt'

with open(filename) as file_object:
    lines = file_object.readlines()

pi_string = ""
for line in lines:
    pi_string += line.rstrip()

print(pi_string[:52] + "...")
print(len(pi_string))

8.2、寫入文件

8.2.1了赵、寫入空文件

需要將文本寫入文件潜支,在調(diào)用open()時(shí)需要提供另一個(gè)實(shí)參,表示要往打開的文件中寫入文本數(shù)據(jù)柿汛。

在這個(gè)實(shí)例中冗酿,調(diào)用open()時(shí),提供了兩個(gè)實(shí)參络断,第一個(gè)是打開文件的名稱裁替,第二個(gè)實(shí)參表示要以寫入模式打開這個(gè)文件。

打開文件有以下幾種模式:

  • 讀取模式 'r' (默認(rèn)只讀取)
  • 寫入模式 'w'
  • 附加模式 'a'
  • 讀取和寫入文件 'r+'
filename = 'programming.txt'

with open(filename, 'w') as file_object:
    file_object.write("I love programming.")

8.2.2貌笨、寫入多行

函數(shù)write不會(huì)在寫入的文本末尾添加換行符弱判,所以如果需要寫入多行的話,注意使用'\n'換行符來(lái)?yè)Q行

像顯示到終端的輸出一樣锥惋,還可以使用空格昌腰,制表符和空行來(lái)設(shè)置這些輸出的格式

def write_file(filename, str):
    # write back to file

    with open(filename, 'w') as file_object:
        file_object.write(str)


str = 'I love programming.\n'
str += 'I love creating new games.\n'
write_file('programming.txt', str)

8.2.3、在文件中追加內(nèi)容

如果要在文件末尾添加內(nèi)容膀跌,而非覆蓋原有的內(nèi)容遭商,可以使用附加模式打開文件,這種模式下捅伤,python不會(huì)在返回文件對(duì)象前清空文件劫流,而將新寫入的內(nèi)容都追加到文件末尾。

def write_file(filename, str):
    # write back to file

    with open(filename, 'a') as file_object:
        file_object.write(str)


str = 'I love programming.\n'
str += 'I love creating new games.\n'
write_file('programming.txt', str)

8.3、異常

python使用異常的特殊對(duì)象來(lái)管理程序執(zhí)行期間發(fā)生的錯(cuò)誤祠汇,當(dāng)出現(xiàn)錯(cuò)誤時(shí)仍秤,python會(huì)創(chuàng)建一個(gè)異常對(duì)象。如果在程序中對(duì)異常對(duì)象進(jìn)行處理座哩,則程序會(huì)繼續(xù)運(yùn)行徒扶,否在程序?qū)⑼V梗@示一個(gè)traceback根穷,其中包含有關(guān)異常的報(bào)告姜骡。

異常是使用try-except代碼塊處理的。

8.3.1屿良、處理ZeroDivisionErro異常

除法運(yùn)算圈澈,除數(shù)如果是0,就會(huì)報(bào)該錯(cuò)誤

try:
  print(5/0)
expect ZeroDivisionError:
  print("You can`t divide by zero!")

8.3.2尘惧、使用異常避免崩潰

print("Give me two numbers, and I`ll divide them.")
print("Enter 'q' to quit.")

while True:
    first_number = input("\nFirst number:\n")
    if first_number == 'q':
        break

    second_number = input("\nSecond number:\n")
    if second_number == 'q':
        break

    try:
        answer = int(first_number) / int(second_number)
    except ZeroDivisionError:
        print("You can`t divide by zero\n")
        continue

    print(answer)

8.3.3康栈、else代碼塊

執(zhí)行錯(cuò)誤的情況放在try-except代碼塊中,將依賴于try代碼塊成功執(zhí)行的代碼應(yīng)放到else中喷橙。代碼流程如下:

  1. python嘗試執(zhí)行try中的代碼啥么,只有可能引發(fā)異常的代碼才放到try代碼塊中
  2. 如果運(yùn)行異常,則看異常的類型是否包含在except中贰逾,如果是悬荣,則執(zhí)行except代碼塊中代碼
  3. 如果運(yùn)行正常,則執(zhí)行else中代碼
print("Give me two numbers, and I`ll divide them.")
print("Enter 'q' to quit.")

while True:
    first_number = input("\nFirst number:\n")
    if first_number == 'q':
        break

    second_number = input("\nSecond number:\n")
    if second_number == 'q':
        break

    try:
        answer = int(first_number) / int(second_number)
    except ZeroDivisionError:
        print("You can`t divide by zero\n")
        continue
    else:
        print(answer)

8.3.4疙剑、處理FileNotFoundError異常

FileNotFoundError異常通常是由于找不到文件所引起的

filename = 'alice.txt'

try:
    with open(filename) as file_obj:
        contents = file_obj.read()
except FileNotFoundError:
    msg = 'Sorry, the file ' + filename + " does not exist."
    print(msg)

8.3.5氯迂、分析文本

分析包含整本書的文本內(nèi)容

split()方法根據(jù)字符串創(chuàng)建一個(gè)單詞列表,使用該方法一空格為分隔符將字符串拆分為多個(gè)部分言缤,并將這部分存儲(chǔ)到一個(gè)列表中嚼蚀。

filename = 'atom.txt'

try:
    with open(filename) as file_obj:
        contents = file_obj.read()
except FileNotFoundError:
    msg = 'Sorry, the file ' + filename + ' does not exist.'
    print(msg)
else:
    words = contents.split()
    num_words = len(words)
    print("The file " + filename + " has about " + str(num_words) + " words.")

8.4、存儲(chǔ)數(shù)據(jù)

程序把客戶提供的信息存儲(chǔ)在列表和字典等數(shù)據(jù)結(jié)構(gòu)中管挟,當(dāng)用戶關(guān)閉程序是轿曙,需要保存這些信息,可以使用模塊json來(lái)存儲(chǔ)數(shù)據(jù)

8.4.1僻孝、json.dump()和json.load()

使用json.dump()將數(shù)據(jù)存儲(chǔ)在文件中拳芙,使用json.load()將文件內(nèi)容讀取到內(nèi)存中

Json.dump()有兩個(gè)參數(shù):

  • 要存儲(chǔ)的數(shù)據(jù)
  • 可用于存儲(chǔ)數(shù)據(jù)的文件對(duì)象
import json

numbers = [2, 3, 4, 5, 8, 21]

filename = 'numbers.json'
with open(filename, 'w') as file_obj:
    json.dump(numbers, file_obj)

    
with open(filename) as file_obj:
    numbers = json.load(file_obj)

print(numbers)

8.4.2、保存和讀取用戶生成的數(shù)據(jù)

對(duì)于用戶生成的數(shù)據(jù)皮璧,使用json保存他們大有裨益。

import json

filename = 'username.json'


def save_user_name(filename):
    username = input("what`s your name?")

    with open(filename, 'w') as file_obj:
        json.dump(username, file_obj)
        print("we`ll remember you when you come back, " + username + "!")


def greet_user(filename):
    with open(filename) as file_obj:
        username = json.load(file_obj)
        print("hello, " + username)


save_user_name(filename)
greet_user(filename)

8.4.3分飞、重構(gòu)

代碼可以正確地運(yùn)行悴务,但是可做進(jìn)一步的改進(jìn)——將代碼劃分為一系列完成具體工作的函數(shù),這樣的過(guò)程被稱為重構(gòu)。重構(gòu)讓代碼更清晰讯檐,更易于理解羡疗,更容易擴(kuò)展

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市别洪,隨后出現(xiàn)的幾起案子叨恨,更是在濱河造成了極大的恐慌,老刑警劉巖挖垛,帶你破解...
    沈念sama閱讀 211,348評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件痒钝,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡痢毒,警方通過(guò)查閱死者的電腦和手機(jī)送矩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,122評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)哪替,“玉大人栋荸,你說(shuō)我怎么就攤上這事∑静埃” “怎么了晌块?”我有些...
    開封第一講書人閱讀 156,936評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)帅霜。 經(jīng)常有香客問(wèn)我匆背,道長(zhǎng),這世上最難降的妖魔是什么义屏? 我笑而不...
    開封第一講書人閱讀 56,427評(píng)論 1 283
  • 正文 為了忘掉前任靠汁,我火速辦了婚禮,結(jié)果婚禮上闽铐,老公的妹妹穿的比我還像新娘蝶怔。我一直安慰自己,他們只是感情好兄墅,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,467評(píng)論 6 385
  • 文/花漫 我一把揭開白布踢星。 她就那樣靜靜地躺著,像睡著了一般隙咸。 火紅的嫁衣襯著肌膚如雪沐悦。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,785評(píng)論 1 290
  • 那天五督,我揣著相機(jī)與錄音藏否,去河邊找鬼。 笑死充包,一個(gè)胖子當(dāng)著我的面吹牛副签,可吹牛的內(nèi)容都是我干的遥椿。 我是一名探鬼主播,決...
    沈念sama閱讀 38,931評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼淆储,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼冠场!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起本砰,我...
    開封第一講書人閱讀 37,696評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤碴裙,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后点额,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體舔株,經(jīng)...
    沈念sama閱讀 44,141評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,483評(píng)論 2 327
  • 正文 我和宋清朗相戀三年咖楣,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了督笆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,625評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡诱贿,死狀恐怖娃肿,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情珠十,我是刑警寧澤料扰,帶...
    沈念sama閱讀 34,291評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站焙蹭,受9級(jí)特大地震影響晒杈,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜孔厉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,892評(píng)論 3 312
  • 文/蒙蒙 一拯钻、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧撰豺,春花似錦粪般、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至凡橱,卻和暖如春小作,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背稼钩。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工顾稀, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人坝撑。 一個(gè)月前我還...
    沈念sama閱讀 46,324評(píng)論 2 360
  • 正文 我出身青樓础拨,卻偏偏與公主長(zhǎng)得像氮块,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子诡宗,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,492評(píng)論 2 348

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