python程序設計 課件 第9章 字符串與文件處理_第1頁
python程序設計 課件 第9章 字符串與文件處理_第2頁
python程序設計 課件 第9章 字符串與文件處理_第3頁
python程序設計 課件 第9章 字符串與文件處理_第4頁
python程序設計 課件 第9章 字符串與文件處理_第5頁
已閱讀5頁,還剩97頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

第9章字符串與文件處理Python程序設計第9章字符串與文件程序的輸入和輸出通常都涉及字符串處理,Python提供了一些在數字和字符串間執行轉換的運算符。字符串是字符序列,而列表可以包含任何類型的值,可以用內置的序列操作來處理字符串和列表。字符串格式化方法(format)可用于生成格式良好的輸出。第9章字符串與文件這一章中還介紹了文本、字節、文件,這些都是數據處理的基礎知識。文件接口不只是針對硬盤里的文件,也包括各種電腦外部設備的存取以及網絡傳輸。幾乎任何內容都以文件的形式存放在文件系統里,包括硬盤、鍵盤、USB、I/O接口等。字符串的概念1文件對話框4字符串格式化2文件處理3目錄字符串數據類型字符串轉換函數簡單字符串處理字符串表示函數輸入/輸出操作9.1定義字符串9.1

定義字符串除了list(列表)與tuple(元組)以外,基本的序列類型還有str(字符串)。str也是容器,是不可變類型,含有一個個字節,如同把字節串接起來,所以稱為字符串(string)。Python中并沒有“字符(character)”類型,需要時可使用含有一個字節的字符串。str是以抽象的字節為元素的Unicode字符串,而不是以固定數目的二進制位為單位,至于字節數據則由新類型bytes負責。9.1.1字符串數據類型在程序中,文本由字符串數據類型表示,視為一個字符序列。可以用引號將一些字符括起來形成字符串字面量。Python還允許字符串由單引號(')分隔,在使用時一定要配對。字符串也可以保存在變量中。下面的例子說明了字符串字面量的兩種形式:>>>str1="Hello">>>str2='spam'>>>print(str1,str2)Hellospam>>>type(str1)<class'str'>>>>type(str2)<class'str'>9.1.1字符串數據類型我們已經知道input函數返回用戶鍵入的任何字符串對象。這意味著如果你希望得到的是一個字符串,就可以使用其“原始”(未轉換)形式的輸入。例如: >>>firstName=input("請輸入你的名字:")

請輸入你的名字:xiaoming >>>print("Hello",firstName) Helloxiaoming這里我們用變量保存用戶名字,然后用該變量將名字打印出來。9.1.1字符串數據類型字符串是一個字符序列。為訪問組成字符串的單個字符,在Python中可以通過“索引”操作來完成。我們可以認為字符串中的位置是被左起編號的,開始為0。下圖用字符串“HelloBob”加以說明。字符串“HelloBob”的索引9.1.1字符串數據類型在字符串表達式中,索引用于訪問字符串中的特定字符的位置,一般形式是<string>[<expr>],其中表達式的值確定了從字符串中選擇哪個字符。例如:>>>greet="HelloBob">>>greet[0]'H'>>>print(greet[0],greet[2],greet[4])Hlo>>>x=8>>>print(greet[x-2])B9.1.1字符串數據類型在n個字符的字符串中,因為索引從0開始,所以最后一個字符的位置是n-1,注意到字符串對象與實際打印輸出之間的差異。在交互中,Pythonshell通過將字符串的值放在單引號中來顯示值,由此告訴我們當前看的是一個字符串對象。實際打印字符串時,不會在字符序列周圍添加引號,只是得到包含在字符串中的文本。可以使用負索引,從字符串的右端索引,這對于獲取字符串的最后一個字符特別有用。>>>greet[-1]'b'>>>greet[-3]'B'9.1.1字符串數據類型索引返回包含較大字符串中單個字符的字符串,也可以從字符串中訪問連續的字符序列或“子字符串”,這是通過“切片”操作來實現的。下面是一些切片:>>>greet[0:3]'Hel'>>>greet[5:9]'Bob'>>>greet[:5]'Hello'>>>greet[5:]'Bob'>>>greet[:]'HelloBob'9.1.1字符串數據類型最后三個示例表明,如果切片中的任何一個表達式缺失,字符串的開始和結束都是假定的默認值,最后的表達式實際上給出了整個字符串。基本的字符串操作總結如表9-1所示。表9-1Python字符串操作9.1.1字符串數據類型若字符串內含有特殊字節,例如新行、TAB以及難以打出來的字節,可使用反斜線“\”作為轉義符號(又稱跳脫字節,跳脫碼),后面跟一串以一定格式標示的字節,形成轉義字符串,分別代表不同的特殊字節(見表9-2)。表9-2轉義字符串>>>'How\'sgoing?' #單引號內以“\”轉義單引號"How'sgoing?">>>s='abc\'def\"ghi' #轉義單引號與雙引號>>>print(s)abc'def"ghi>>>s='abc\tdef\n' #轉義TAB與換行>>>s'abc\tdef\n'9.1.1字符串數據類型>>>print(s)abcdef #有個TAB #有個換行>>>print('abc\newlinedef') #注意,“\n”會變成換行AbcEwlinedef>>>'\x61\x62\x63\x09\x64' #以十六進制數值表示'abc\td''abc\td'>>>'\141\142\143\011\144' #以八進制數值表示'abc\td'>>>'abc\qdef' #不正確的轉義字符串'abc\\qdef' #反斜線“\”會被保留9.1.1字符串數據類型9.1.1字符串數據類型如果字符串跨越多行,使用三重引號較為方便,三重引號之間的換行與引號都無須轉義;但若需要輸出三個連續引號,還是需要轉義。當想要在程序代碼里置入大量HTML、XML、JSON這樣的標示語言內容時,就適合使用三重引號。>>>s='''abcdef...ghijklmno #之間各夾一個TAB...pqr\t\nstu #也可轉義TAB與換行...vw'''>>>s'abcdef\nghi\tjkl\tmno\npqr\t\nstu\nvw'9.1.1字符串數據類型>>>print(s) #輸出來的樣子abcdefghijklmnopqrstuvw>>>'''abc\'\'\'def''' #每個引號都轉義"abc'''def">>>'''abc''\'def''' #只轉義一個引號,"abc'''def" #只要沒有連續三個引號即可9.1.1字符串數據類型9.1.1字符串數據類型因為反斜線“\”被當作轉義字節,有時候字符串中須含有大量反斜線時,就不太方便,此時可在開頭引號前加上“r”或“R”,代表raw(原始)之意,其作用是取消大部分的轉義字符串,但仍可轉義引號。當需要表達Windows的路徑時,可使用此種表達方式。>>>'\n' #一個字節,換行'\n'>>>r'\n' #兩個字節,反斜線與換行'\\n'>>>"\"" #一個字節,雙引號'"'>>>r'\\' #兩個字節,都是反斜線'\\\\'>>>r"\"" #仍可轉義引號,但反斜線也會被留下'\\"'9.1.1字符串數據類型>>>print('C:\newfolder\today') #\n與\t都是轉義字符串C:ewfolderoday>>>print(r'C:\newfolder\today') #加上rC:\newfolder\today>>>r'C:\' #不能以“\'”結尾,意義不清楚,

File"<stdin>",line1 #結尾引號被反斜線轉義掉了

r'C:\'^SyntaxError:EOLwhilescanningstringliteral9.1.1字符串數據類型>>>s=r'abc\#加上r后,“反斜線”與“換行”代表原來的字節...defghi' #不代表延續到下一行>>>s #s中有反斜線與換行'abc\\\ndefghi'9.1.1字符串數據類型9.1.1字符串數據類型以字面值的方式建立字符串對象,之后便可運用內置函數、序列類型共同的操作動作、字串特有的方法、各種模塊來操作字符串,因為字符串是不可變對象,所以在操作運算之后,都會得到新的字符串對象。9.1.2字符串轉換函數Python中,為了方便對字符串中的字母進行大小寫轉換,提供了幾個方法,分別是title()、lower()、upper()、capitalize()和swapcase()。

upper()全轉換成大寫

lower()全轉換成小寫

title()標題首字母大寫

swapcase()大小寫字母互換

capitalize()首字母大寫,其余全部小寫9.1.2字符串轉換函數例如,下面是幾個簡單的代碼:str="chengxuitquan"print(str.upper()) #把所有字符中的小寫字母轉換成大寫字母print(str.lower()) #把所有字符中的大寫字母轉換成小寫字母print(str.title()) #把每個單詞的第一個字母轉化為大寫,其余小寫print(str.capitalize()) #把第一個字母轉化為大寫字母,其余小寫print(str.swapcase()) #把大小寫字母互換運行結果是:CHENGXUITQUANchengxuitquanChengXuItQuanChengxuitquanCHENGXUITQUAN9.1.3簡單字符串處理函數許多計算機系統使用用戶名和密碼組合來認證系統用戶。系統管理員必須為每個用戶分配唯一的用戶名,用戶名通常來自用戶的實際姓名。以英文用戶名為例,一種生成用戶名的方案是使用用戶的第一個首字母,然后是用戶姓氏的最多七個字母。利用這種方法,ZaphodBeeblebrox的用戶名將是“zbeebleb”,而JohnSmith就是“jsmith”。下面,我們按照基本的輸入、處理、輸出模式編寫一個程序,讀取一個人的名字并計算相應的用戶名。為簡潔起見,在程序中包含算法的概要作為注釋。【程序實例9-1】生成用戶名的簡單字符串處理程序。#username.pydefmain():print("這個程序生成計算機用戶名。\n")#獲取用戶的名字和姓氏

first=input("請輸入您的名字(全字母小寫):")last=input("請輸入您的姓氏(全字母小寫):")#將第一個首字母連接到姓氏的7個字符

uname=first[0]+last[:7]#輸出用戶名

print("您的用戶名是:",uname)main()9.1.3簡單字符串處理函數9.1.3簡單字符串處理函數這個程序首先利用input從用戶處獲取字符串,然后組合使用索引、切片和連接等方法來生成用戶名。在第一個print語句中將換行符(\n)放在字符串的末尾,用以輸出一個空行。這是一個簡單的技巧,輸出一些額外的空白可以更好看一些。9.1.3簡單字符串處理函數再來看一個例子。假設要打印給定月份數對應的月份縮寫。程序的輸入是一個代表一個月份(1~12)的int數值,輸出的是相應月份的縮寫。例如輸入3,則輸出應為Mar,即3月。為此,必須根據用戶給出的數字,確定一種合適的月份輸出。這里可以通過一些巧妙的字符串切片來編寫程序,基本思想是將所有月份名稱存儲在一個大字符串中: months="JanFebMarAprMayJunJulAugSepOctMovDec"通過切出適當的子字符串來查找特定的月份,訣竅是計算在哪里切片。由于每個月由三個字母表示,如果知道一個給定的月份在字符串中的開始位置,就可以很容易地提取縮寫: MonthAbbrev=months[pos:pos+3]這將獲得從pos指示位置開始的長度為3的子串。9.1.3簡單字符串處理函數每個月份的位置都是3的倍數,而字符串索引從0開始。這樣,為了得到正確的倍數,我們從月數中減去1,然后乘以3。所以對于1,得到(1–1)*3=0*3=0,對于12,我們有(12–1)*3=11*3=33。【程序實例9-2】打印給定月份數字對應的月份縮寫,其中注釋記錄了程序的算法。#month.pydefmain():#months用作查找表

months="JanFebMarAprMayJunJulAugSepOctNovDec"n=int(input("輸入月份編號(1-12):"))#以月為單位計算月份n的起始位置

pos=(n-1)*3#從幾個月抓取適當的切片

monthAbbrev=months[pos:pos+3]#打印結果

print("月份縮寫是",monthAbbrev+".")main()9.1.3簡單字符串處理函數9.1.3簡單字符串處理函數程序分析:該程序的最后一行利用字符串連接,將句點放在月份縮寫的末尾。下面是程序輸出的示例:輸入月份編號(1-12):4月份縮寫是Apr.想一想:這個例子使用“字符串作為查找表”方法,它有一個弱點,即僅當子串都有相同的長度(在本例中是3)時才有效。假設我們希望編寫一個程序,輸出給定數字的完整月份名稱,該如何實現呢?9.1.4字符串表示函數在計算機內部,數字以二進制符號(0和1組成的序列)存儲,計算機CPU中包含有用這種表示方法進行運算的電路,文本信息也以完全相同的方式表示。在底層,計算機操作文本和進行數字運算是完全一樣的。如今的計算機系統主要使用ASCII(美國信息交換標準代碼)的工業標準編碼。ASCII用數字0~127來表示通常計算機鍵盤上的字符以及被稱為控制代碼的某些特殊值,用于協調信息的發送和接收。例如,大寫字母A~Z由值65~90表示,小寫字母的代碼值為97~122。ASCII編碼中缺少一些其他語言所需要的符號,為此,國際標準組織(ISO)開發了擴展ASCII編碼。大多數現代系統正在向Unicode轉移,這是一個更大的標準,旨在包括幾乎所有書面語言的字符。Python字符串支持Unicode標準,因此,只要你的操作系統有適當的字體來顯示字符,就可以處理來自任何語言的字符。9.1.4字符串表示函數Python提供了幾個內置函數,允許在字符和字符串中表示它們的數字值之間來回切換。例如ord函數返回單字符串的數字(“ordinal”)編碼,而chr相反。下面是一些交互的例子:>>>ord("a")97>>>ord("A")65>>>chr(97)'a'>>>chr(90)'z'9.1.4字符串表示函數你會注意到這些結果與字符的ASCII編碼一致。按照設計,Unicode使用的相應代碼與ASCII最初定義的127個字符相同。但Unicode還包括更多其他的字符。例如,希臘字母pi是字符960,歐元的符號是字符8364。在計算機中,底層CPU處理固定大小的內存。最小可尋址段通常為8位,稱為存儲器字節。單個字節可以存儲28=256個不同的值。這足以代表每個可能的ASCII字符。但是,單個字節遠遠不足以存儲所有10萬個可能的Unicode字符。為了解決這個問題,Unicode標準定義了將Unicode字符打包成字節序列的各種編碼方案。最常見的編碼稱為UTF-8。UTF-8是一種可變長度編碼方案,用單個字節存儲ASCII子集中的字符,但可能需要最多四個字節來表示一些更為深奧的字符。9.1.5輸入/輸出操作有些程序,即使主要不是進行文本操作,也經常需要用到字符串。例如,考慮一個財務分析程序,其中的某些信息(如日期)必須以字符串形式輸入。在進行一些數字處理之后,分析的結果通常是一個格式良好的報告,包括用于標記和解釋數字、圖表、表格和圖形的文本信息,需要字符串操作來處理這些基本的輸入和輸出任務。9.1.5輸入/輸出操作作為一個具體的例子,我們將月份縮寫程序擴展成日期轉換。用戶輸入一個日期,例如“05/24/2020”,程序將顯示日期為“May24,2020”。下面是該程序的算法:以mm/dd/yyyy格式輸入日期(dateStr)將dateStr拆分為月,日和年字符串將dateStr轉換為月份數字使用月份編號查找月份名稱在MonthDay,Year中創建一個新的日期字符串輸出新的日期字符串可以用字符串操作在代碼中直接實現算法的前兩行:dateStr=input("輸入日期(mm/dd/yyyy):")monthStr,dayStr,yearStr=datestr.split("/")9.1.5輸入/輸出操作這里得到一個字符串的日期,并以斜杠分隔。然后利用同時賦值,將三個字符串的列表“分拆”到變量monthStr、dayStr和yearStr中。接下來是將monthStr轉換為適當的數字(使用int),然后用該值查找正確的月份名稱。下面是代碼:months=["January","February","March","April","May","June","July","August","September","October","November","December"]monthStr=months[int(monthStr)-1]使用索引表達式int(monthStr)-1是因為列表索引從0開始。程序的最后一步是以新格式拼出日期。注意程序中如何使用連接實現緊跟日期的逗號。 print("轉換的日期是:",monthStr,dayStr+",",yearStr)【程序實例9-3】將日期格式“mm/dd/yyyy”轉換為“月,日,年”。#dateconvert.pydefmain():#得到日期

dateStr=input("輸入日期(mm/dd/yyyy):")#分成組件

monthStr,dayStr,yearStr=dateStr.split("/")9.1.5輸入/輸出操作#將monthStr轉換為月份名稱

months=["January","February","March","April","May","June","July","August","September","October","November","December"]monthStr=months[int(monthStr)-1]#輸出結果以月日年格式顯示

print("轉換的日期是:",monthStr,dayStr+",",yearStr)main()9.1.5輸入/輸出操作9.1.5輸入/輸出操作程序分析:運行時,輸出如下所示:輸入日期(mm/dd/yyyy):05/24/2020轉換的日期是:May24,2020我們常常也需要將數字轉成字符串。在Python中,大多數據類型可以用str函數轉換為字符串,例如:>>>str(500)'500'>>>value=3.14>>>str(Value)'3.14'>>>print("Thevalueis",str(value)+".")Thevalueis3.14.9.1.5輸入/輸出操作注意最后一個例子。通過將值轉換為字符串,可以用字符串連接在句子的尾處放置句點。如果不先將值轉換為字符串,Python會將“+”解釋為數字運算產生錯誤,因為“.”不是數字。現在有了一套完整的操作,用于在各種Python數據類型之間轉換值(見表9-3)。表9-3類型轉換函數9.1.5輸入/輸出操作將數字轉換為字符串的一個常見原因,是字符串操作可用于控制值的打印方式。例如,執行日期計算的程序必須將月、日和年作為數字操作,而格式化輸出時這些數字將被轉換回字符串。9.2

字符串格式化9.2

字符串格式化基本的字符串操作對于簡單格式的格式化輸出是有用的,但是構建復雜輸出時就可能很麻煩,為此Python提供了一個強大的字符串格式化操作。【程序實例9-4】以外幣(美元)為例,一個計算美元零錢的程序。#change.pydefmain():print("貨幣兌換")print()print("請輸入每種硬幣類型的數量。")quarters=eval(input("25分:"))dimes=eval(input("10分:"))nickels=eval(input("5分:"))pennies=eval(input("1分:"))total=quarters*.25+dimes*.10+nickels*.05+pennies*.01print()print("你兌換的總值是",total)main()9.2

字符串格式化9.2

字符串格式化程序分析:下面是上述程序的運行結果:貨幣兌換請輸入每種硬幣類型的數量。25分:610分:05分:01分:0你兌換的總值是1.59.2

字符串格式化注意,最終值是以一位小數的形式給出的,這可以通過更改程序的最后一行來解決,例如:print("你的兌換總值是${0:0.2f}".format(total))現在程序打印以下消息:

你的兌換總值是$1.50其中,format方法是Python內置的字符串方法,它用字符串作為模板,值作為參數提供,插入到該模板中,從而形成一個新的字符串。字符串格式化的形式為: <template-string>.format(<values>)模板字符串中的花括號({})標記出“插槽”,提供的值將插入該位置。花括號中的信息指示插槽中的值以及值應如何格式化。9.2

字符串格式化Python格式化操作符非常靈活,通常插槽說明總是具有以下形式: {<index>:<format-specifier>}即:{<索引>:<格式說明符>}<索引>告訴哪個參數被插入到插槽中。插槽描述的索引部分是可選的,省略索引時,參數僅以從左到右的方式填充到插槽中。索引從0開始。上面的例子中有一個插槽,索引0用于表示第一個(也是唯一的)參數插入該插槽。冒號后的描述部分指定插入插槽時該值的外觀。再次回到示例,格式說明符為0.2f,此說明符的格式為<寬度>.<精度><類型>。<寬度>指明值應占用多少“空間”。如果值小于指定的寬度,則用額外的字符填充(默認值是空格)。<精度>為2,告訴Python將值舍入到兩個小數位。最后,<類型>字符f表示該值應顯示為定點數。這意味著,將始終顯示指定的小數位數,即使它們為0。9.2

字符串格式化對格式說明符的完整描述較難理解,最簡單的模板字符串只是指定在哪里插入參數。下面,我們通過幾個例子來熟悉它。>>>"Hello{0}{1},youmayhavewon${2}".format("Mr.","Smith",10000)‘HelloMr.Smith,youmayhavewon$10000.’(您好史密斯先生,您可能贏得$10000。)通常,我們想要控制一個數學值的寬度和精度:>>>"Thisint,{0:5},wasplacedinafieldofwidth5".format(7)'Thisint,7,wasplacedinafieldofwidth5.'(“這個整數7放置在寬度為5的字段中。”)>>>"Thisint,{0:10},wasplacedinafieldofwidth10".format(7)'Thisint,7,wasp1acedinafieldofwidth10'9.2

字符串格式化>>>"Thisfloat,{0:10.5},haswidth10andprecision5".format(3.1415926)'Thisfloat,3.1416,haswidth10andprecision5'>>>"Thisfloat,{0:10.5f},isfixedat5decimalplaces".format(3.1415926)'Thisfloat,3.14159,isfixedat5decimalplaces'9.2

字符串格式化>>>"Thisfloat,{0:0.5},haswidth0andprecision5".format(3.1415926)'Thisfloat,3.1416,haswidth0andprecision5'>>>"Compare{0}and{0:0.20}".format(3.14)'Compare3.14and3.14000000000001243'9.2

字符串格式化9.2

字符串格式化對于正常(非定點)浮點數,精度指明要打印的有效數字的個數。對于定點(由指定符末尾的f表示),精度表示小數位數。在最后一個示例中,相同的數字以兩種不同的格式打印出來。一般來說,Python只顯示一個接近的、舍入的浮點型。使用顯式格式化可以查看到完整結果,直到最后一位。9.2

字符串格式化默認情況下數值是右對齊的,而字符串在其字段中是左對齊的。通過在格式說明符的開頭包含顯式調整字符,可以更改默認行為。對于左、右和中心對齊,所需的字符分別為<、>和^。>>>"左對齊:{0:<5}".format("嗨!")'左對齊:嗨!'>>>"右對齊:{0:>5}".format("嗨!")'右對齊:嗨!'>>>"居中:{0:^5}".format("嗨!")'居中:嗨!'9.2

字符串格式化假設我們為一家銀行編寫一個計算機系統。你的客戶得知收費“非常接近107.56美元”,恐怕不會太高興。顯然人們希望銀行的記錄是精確的。即使給定值中的誤差量非常小,因為如果進行大量計算,小誤差也可能導致誤差累積成真實的金額。較好的方法是確保程序用準確的值來表示錢。我們可以用美分來記錄貨幣,并用int來存儲它。然后,我們可以在輸出步驟中將它轉換為美元和美分。假設我們處理正數,如果total代表以分為單位的值,那么我們可以通過整數除法total//100得到美元數,通過total%100得到美分數。這兩個都是整數計算,因此會給出確切的結果。下面是更新后的程序:【程序實例9-5】以外幣(美元)為例,一個以美分計算的總現金。#change2.pydefmain():print("貨幣兌換\n")print("P請輸入每種硬幣類型的數量。")quarters=int(input("25分:"))dimes=int(input("10分:"))nickels=int(input("5分:"))pennies=int(input("1分:"))9.2

字符串格式化total=quarters*25+dimes*10+nickels*5+penniesprint("你兌換的總值是${0}.{1:0>2}".format(total//100,total%100))main()9.2

字符串格式化9.2

字符串格式化程序分析:最后,打印語句被分成了兩行。通常一個語句應該在行末結束,但有時將較長的語句分成較小的部分可能更好。print語句中的字符串格式化包含兩個插槽,一個用于美元,是int,另一個用于美分。美分插槽說明了格式說明符的另一種變化,其值用格式說明符“0>2”打印。前面的0告訴Python用0來填充字段(如果必要),確保10美元5美分這樣的值打印為10.05美元,而不是10.5美元。認識文件打開模式多行字符串處理文件示例程序:批處理用戶名9.3文件處理9.3

文件處理字處理是字符串數據的應用程序。所有字處理程序都有一個關鍵特征,即能夠保存和讀取文檔用作磁盤文件。文件輸入和輸出實際上是另一種形式的字符串處理。9.3.1認識文件首先請在文字編輯器軟件中鍵入如下內容,將文件取名為test.txt,然后與下面的程序文件放在同一個目錄里。【程序實例9-6】測試用文檔(test.txt)。HelloPython!Howareyou?abc1239.3.1認識文件【程序實例9-7】打開文件。#test.pyfin=open('test.txt') #打開文件print(fin.readline()) #讀取一行文字并輸出forlineinfin: #迭代每一行

print(line) #輸出fin.close() #關閉9.3.1認識文件9.3.1認識文件程序分析:程序將讀取并輸出文檔內容。在存取文件時必須先“打開”,得到代表該文件的對象?n,透過它所提供的接口來存取文件內容,例如方法readline可讀取一行文字,且此對象符合可迭代項抽象類型,所以可交給迭代協定的接收方(例如此例中的for循環),不斷地拿出文件內容的“下一行”,直到文件結束。最后應調用文件對象的方法close做“關閉”的動作,因為打開文件會占用系統資源,應做好清理收尾的工作。使用print(line)輸出一行時,除了輸出文件每一行結尾的“新行”字節,print缺省還會再輸出一個新行字節,所以輸出時多了一行空白行,可以用“print(line,end='')”改為輸出空字符串。9.3.2打開模式調用open時,第一個參數以字符串指定欲打開文件的路徑與文件名,第二個參數以字符串指定“模式”,缺省為讀取模式與文本模式,所以open('test.txt')等同于open('test.txt','r'),也等同于open('test.txt','rt'),其中r代表讀取模式,t代表文字模式(參見表6-4)。9.3.2打開模式表9-4文件打開模式9.3.2打開模式下面程序段可復制文件test.txt的內容到新文件(testw.txt),以w模式建立新文件,調用方法write寫入。fin=open('test.txt')fw=open('testw.txt','w') #w,寫入模式forlineinfin:print(line)fout.write(line) #調用write方法寫入數據fin.close()fout.close()9.3.2打開模式文件對象的方法readline可讀出一行,readlines則讀出每一行并放在列表里返回,所以也可使用“forlinein?n.readlines()”,但這么做會一次載入文件的全部內容,再進行迭代,效率較低。9.3.3多行字符串文件是存儲在輔助存儲器(通常是磁盤驅動器)上的數據序列。文件可以包含任何數據類型,但最簡單的文件是文本文件。文本文件可以被人閱讀和理解,可以使用通用文本編輯器(諸如IDLE)和字處理程序來創建和編輯。Python中的文本文件可以非常靈活,因為它很容易在字符串和其他類型之間轉換。可以將文本文件看成是一個(可能很長的)字符串,恰好存儲在磁盤上。當然,典型的文件通常包含多于一行的文本。特殊字符或字符序列用于標記每行的結尾。Python為我們處理不同的行結束標記約定,只要求使用“\n”來表示換行符即可。9.3.3多行字符串我們來看一個具體的例子,假設在文本編輯器中鍵入以下行:HelloWorldGoodbye32如果存儲到文件,會得到以下字符序列: Hello\nWorld\n\nGoodbye32\n9.3.3多行字符串在得到的文件/字符串中,空行變成一個換行符,這就像我們將換行字符嵌入到輸出字符串,用一個打印語句生成多行輸出一樣。上面例子的交互式打印結果如下:>>>print("Hello\nWorld\n\nGoodbye32\n")HelloWorldGoodbye32>>>如果只是在shell中對一個包含換行符的字符串求值,將再次得到嵌入換行符的表示形式:>>>"Hello\nWorld\n\nGoodbye32\n"'Hello\nWorld\n\nGoodbye32\n'只有當打印字符串時,特殊字符才會影響字符串的顯示方式。9.3.4處理文件(1)一次性讀取。例如想要讀取txt小說(為簡化,txt文件中只包含一段文字):file='novel.txt'withopen(file)asfile_object:contents=file_object.read()print(contents)運行結果:Itisatruthuniversallyacknowledged,thatasinglemaninpossessionofagoodfortune,mustbeinwantofawife.要使用文件,就必須先打開它,所以這里使用了函數open()。函數open()接受一個參數:即要打開的文件路徑。如果只有文件名,那么Python會在當前執行文件的所在目錄來查找指定的文件。9.3.4處理文件關鍵字with會在程序不再需要訪問文件或出現異常的情況下關閉文件,通常只管打開文件使用它即可。9.3.4處理文件(2)文件路徑。函數open()接收的參數如果只有文件名,那么Python會在當前執行的.py文件所在的目錄中查找文件。也可以提供文件路徑,讓Python到指定的文件目錄中去查找所需要的文件。相對路徑語法形如: withopen('xxx\novel.txt')asfile_object:一般來說,在Windows系統中,在文件路徑中使用反斜杠(“\”),Linux與OS使用的是斜杠(“/”)。實際測試,在Windows系統中,斜杠與反斜杠都支持。當然也可以使用絕對路徑。如果使用的是絕對路徑,那么在Windows系統中,文件路徑必須使用反斜杠。形如: withopen('F:/python_projects/xxx/novel.txt')asfile_object:因為絕對路徑一般較長,所以將其存儲在變量中,然后再傳入open()函數。9.3.4處理文件(3)逐行讀取。可以對文件對象使用for循環,逐行讀取文件內容。withopen(file)asfile_object:forline_contentinfile_object:print(line_content.rstrip())運行結果與之前的“一次性讀取”示例結果相同。在txt文件中,每行的末尾都存在一個看不見的換行符。為了去除這些多余的空白行,可以使用了rstrip()函數,這會刪除string字符串末尾的空格。9.3.4處理文件(4)在with外訪問使用關鍵字with時,open()函數所返回的文件對象,只能在with代碼塊中使用。如果需要在with代碼塊之外訪問文件的內容,那么可以在with代碼塊之內,將文件中的各行內容存儲在列表變量中,然后就可以在with代碼塊之外,通過該列表變量訪問文件內容。withopen(file)asfile_object:contents=file_object.readlines()content_str=''forcontentincontents:content_str+=contentprint('content_str='+content_str)print('len='+str(len(content_str)))9.3.4處理文件運行結果:content_str=Itisatruthuniversallyacknowledged,thatasinglemaninpossessionofagoodfortune,mustbeinwantofawife.len=117注意:讀取文本文件時,Python會將文件中的所有文本都解釋為字符串。如果我們需要將其中的文本解釋為數字,那么就必須使用函數int()或者float()將其轉換為整數或者浮點數。9.3.4處理文件Python對數據量沒有大小限制,只要系統內存足夠多。文件處理的具體細節在編程語言之間有很大不同,但實際上所有語言都共享某些底層的文件操作概念。首先,我們需要一些方法將磁盤上的文件與程序中的對象相關聯,這個過程稱為“打開”文件。一旦文件被打開,其內容即可通過相關聯的文件對象來訪問。其次,我們需要一組可以操作文件對象的操作,這至少包括允許從文件中讀取信息并將新信息寫入文件的操作。最后,當完成文件操作,它會被“關閉”,這將確保所有記錄工作都己完成,從而保持磁盤上的文件和文件對象之間的一致。9.3.4處理文件這種打開和關閉文件的思想,與字處理程序處理文件的方式密切相關,但不完全相同。例如在MicrosoftWord中打開文件時,該文件實際上是從磁盤讀取并存儲到RAM中。此時,在編程意義上文件被關閉,“編輯文件”時改變的是內存中的數據,而不是文件本身。這些更改不會顯示在磁盤上的文件中,除非通知應用程序“保存”。在Python中使用文本文件很容易。第一步是用open函數創建一個與磁盤上的文件相對應的文件對象。通常文件對象立即分配給變量,如下所示: <variable>=open(<name>,<mode>)這里的name是一個字符串,它提供了磁盤上文件的名稱;mode參數是字符串“r”或“w”,這取決于我們打算從文件中讀取還是寫入文件。9.3.4處理文件例如,要打開一個名為“numbers.dat”的文件進行讀取,可以使用如下語句: infile=open("numbers.dat","r")接著可以利用文件對象infile從磁盤讀取mumbers.dat的內容。Python提供了三個相關操作從文件中讀取信息:<file>.read():將文件的全部剩余內容作為單個(可能是大的、多行的)字符串返回。<file>.readline():返回文件的下一行。即所有文本,直到并包括下一個換行符。<file>.readlines():返回文件中剩余行的列表。每個列表項都是一行,包括結尾處的換行符。【程序實例9-8】用read操作將文件內容打印到屏幕上。#printfile.pydefmain():fname=input("輸入文件名:")infile=open(fname,"r")data=infile.read()print(data)main()9.3.4處理文件9.3.4處理文件程序分析:程序首先提示用戶輸入文件名,然后打開文件以便讀取變量infile。雖然可以使用任意名稱作為變量,但這里使用infile強調該文件正在用于輸入。然后將文件的全部內容讀取為一個大字符串并存儲在變量data中,打印data從而顯示內容。readline操作可用于從文件讀取下一行。對readline的連續調用從文件中獲取連續的行,這類似于輸入,它以交互方式讀取字符,直到用戶按下回車鍵。每個對輸入的調用從用戶獲取另一行。但要記住一件事,readline返回的字符串總是以換行符結束,而input會丟棄換行符。9.3.4處理文件作為一個快速示例,這段代碼打印出文件的前五行:Infile=open(someFile,"r")foriinrange(5):line=infile.readline()print(line[:-1])請注意,利用切片去掉行尾的換行符。由于print自動跳轉到下一行(即它輸出一個行符),打印在末尾帶有顯式換行符時,將在文件行之間多加一個空行輸出。或者,可以打印整行,但告訴print不添加自己的換行符。 print(line,end="")9.3.4處理文件循環遍歷文件全部內容的一種方法,是使用readlines讀取所有文件,然后循環遍歷結果列表:infile=open(someFile,"r")forlineininfile.readlines():#在這里處理一行infile.close()9.3.4處理文件當然,這種方法的潛在缺點是文件可能非常大,并且一次將其讀入列表可能占用太多的RAM。有一種簡單的替代方法,Python將文件本身視為一系列行。所以循環遍歷文件的行可以直接如下進行,每次處理文件的一行:infile=open(someFile,"r")forlineininfile:#在這里處理一行infile.close()9.3.4處理文件打開用于寫入的文件,讓該文件準備好接收數據。如果給定名稱的文件不存在,就會創建一個新文件。注意:如果存在給定名稱的文件,Python將刪除它并創建一個新的空文件。寫入文件時,應確保不要破壞以后需要的任何文件!下面是打開文件用作輸出的示例: Outfile=open("mydate.out","w")將信息寫入文本文件最簡單的方法是用已經熟悉的print函數。要打印到文件,只需要添加一個指定文件的關鍵字參數,這個行為與正常打印完全相同,只是結果被發送到輸出文件而不是顯示在屏幕上: print(…,file=<outputFile>)9.3.5示例程序:批處理用戶名如果為大量用戶設置賬戶,則該過程一般是以“批處理”方式進行。在批處理時,程序輸入和輸出通過文件完成。下面我們設計程序用于處理一個包含名稱的文件。輸入文件的每一行將包含一個新用戶的姓和名,用一個或多個空格分隔。該程序產生一個輸出文件,其中包含每個生成的用戶名的行。【程序實例9-9】以批處理模式創建用戶名文件。#userfile.pydefmain():print("該程序從名稱文件創建用戶名文件。")#獲取文件名

infileName=input("這些名稱在哪個文件里?")outfileName=input("用戶名應該放在哪個文件中?")9.3.5示例程序:批處理用戶名#打開該文件

infile=open(infileName,"r")outfile=open(outfileName,"w")#處理輸入文件中的每一行

forlineininfile:#從行中獲取名字和姓氏

first,last=line

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論