[Python學習筆記]文件的讀取寫入


文件與文件路徑

路徑合成 os.path.join()

在Windows上,路徑中以倒斜杠作為文件夾之間的分隔符,Linux或OS X中則是正斜杠。如果想要程序正確運行於所有操作系統上,就必須要處理這種情況。os.path.join()方法可以正確的根據不同的操作系統來合成路徑,它的用法如下:

>>> import os
>>> os.path.join("Program", "QQ", "Pet")
'Program\\QQ\\Pet'  # 在windows下返回的結果
'Program/QQ/Pet'    # 在Linux或OS X下返回的結果

>>> myFiles = ["accounts.txt", "details.csv", "invite.docx"]
>>> for filename in myFiles:
...     print(os.path.join("C:\\Users\\Dereen", filename))
C:\Users\Dereen\accounts.txt
C:\Users\Dereen\details.csv
C:\Users\Dereen\invite.docx

查看並改變當前工作目錄

使用os.getcwd()來獲取當前工作目錄,使用os.chdir()來改變當前工作目錄。這么做的意義是所有沒有從根文件夾開始的文件名或路徑,都假定在當前工作目錄下。如果當前工作目錄錯誤容易引發各種該問題,或者不想用當前工作目錄作為根目錄,而是想用別的目錄作為根目錄。

>>> os.getcwd()
'F:\\Learn\\Automate-the-Boring-Stuff-with-Python-Solutions'
>>> os.chdir("C:\\Windows\\system32")
>>> os.getcwd()
'C:\\Windows\\system32'

絕對路徑與相對路徑

  • “絕對路徑”:總是從根文件夾開始;
  • “相對路徑”:它相對於程序的當前工作目錄。

例如:C:\Program Files\QQ\music

假如當前工作目錄為C:\Program Files,則對music文件夾來說,其相對路徑為:.\QQ\music,絕對路徑為:C:\Program Files\QQ\music

創建新文件夾 os.makedirs()

>>> os.makedirs(".\\color\\green")

上面這個命令會直接在當前文件夾下創建新文件夾color並在其下創建新文件夾green

絕對路徑與相對路徑互轉

  • 相對路徑轉絕對路徑:os.path.abspath(path)將返回參數的絕對路徑的字符串。
  • 絕對路徑轉相對路徑:os.path.relpath(path, start)將返回從start路徑到path路徑的相對路徑的字符串。(如果沒有提供start,就是用當前工作目錄作為開始路徑)
  • 判斷一個路徑是否為絕對路徑:os.isabs(path)如果是就返回True,不是就返回False。

例子:

>>> os.path.abspath(".")
'F:\\Learn\\Automate-the-Boring-Stuff-with-Python-Solutions'
>>> os.path.relpath("C:\\Windows", "C:\\Hello\Kitty\S")
'..\\..\\..\\Windows'
>>> os.path.isabs(".")
False

目錄名稱和基本名稱(路徑分割)

os.path.dirname(path)返回path參數中最后一個斜杠之前的所有內容;os.path.basename(path)返回path參數中最后一個斜杠之后的所有內容。os.path.split(path)返回一個元組,同時包含2者。

例子:

>>> path = "C:\\Windows\\system32\\tasks\\calc.exe"
>>> os.path.dirname(path)
'C:\\Windows\\system32\\tasks'
>>> os.path.basename(path)
'calc.exe'
>>> os.path.split(path)
('C:\\Windows\\system32\\tasks', 'calc.exe')

如果想要路徑進行進一步的分割,就要調用字符串中的split()方法。並向其傳入os.path.sep參數。(os.path.sep在不同的操作系統下,值也不同,在windows下值為"\"),例子:

>>> path.split(os.path.sep)
['C:', 'Windows', 'system32', 'tasks', 'calc.exe']

查看文件大小和文件夾內容

使用os.path.getsize(filepath)來查看單個文件的大小,注意不能查看文件夾的大小。使用os.listdir(path)來查看該目錄下的所有文件及文件夾。二者組合使用可以計算文件夾的大小。例如:

>>> os.path.getsize("C:\\Windows\\System32\\calc.exe")
27648
>>> os.listdir("C:\\Windows\\System32")
['0409', '@AppHelpToast.png', '@AudioToastIcon.png', '@BackgroundAccessToastIcon.png', '@bitlockertoastimage.png', '@edptoastimage.png', '@EnrollmentToastIcon.png', 
--snip--
'xwreg.dll', 'xwtpdui.dll', 'xwtpw32.dll', 'zh-CN', 'zh-HANS', 'zh-TW', 'zipcontainer.dll', 'zipfldr.dll', 'ztrace_maps.dll']
>>> totalSize = 0
>>> for file in os.listdir("C:\\Windows\\System32"):
...     totalSize += os.path.getsize(os.path.join("C:\\Windows\\System32", file))
...
>>> print(totalSize)
2249563697

檢查路徑有效性

使用os.path.exists(path)檢查path所指的文件或文件夾是否存在;os.path.isdir()檢查參數path傳入的值是否為一個文件夾;os.path.isfile()檢查參數path傳入的值是否為一個文件。例如;

>>> os.path.exists(r"C:\Windows")
True
>>> os.path.isdir(r"C:\Windows")
True
>>> os.path.isfile(r"C:\Windows")
False

文件讀寫過程

在開始前先介紹一下文件的分類:

  • 純文本文件:只包含基本文本字符,不包含字體、大小、顏色和其他信息。例如:.txt文件、.md文件和.py文件;
  • 二進制文件:所有其他文件類型,例如.pdf文件、.docx文件等;使用純文本文件編輯器打開一個二進制文件就會顯示亂碼,如圖:

在Python中,讀寫文件有3個步驟:

  1. 調用open()函數,返回一個File對象;
  2. 調用File對象的read()write()方法;
  3. 調用File對象的close()方法,關閉該文件。

打開文件

使用open()函數打開文件,在打開文件時可同時傳入參數(默認為‘r’,只讀模式)。該函數會返回一個對象,該對象包含文檔內容以及名稱、打開模式以及文檔編碼模式。例如:

>>> content = open("README.md", "w")
>>> content
<_io.TextIOWrapper name='README.md' mode='w' encoding='UTF-8'>
傳遞參數 含義
r 只讀模式打開,即只能讀取文件內容不能寫入
w 可以寫入內容,但是會清除原文檔所有內容
x 用於創建並寫新文檔
a 用於在文檔尾部進行擴展(不會清除原文檔內容)

讀取文件內容

在上一步中,我們使用open()函數打開文件並返回了一個文件對象,這里,我們可以使用read()readlines()方法讀取這個文件對象中的內容。其中,前者將文件中的所有內容讀取為一個大字符串,后者按行讀取文件,每行為一個字符串並最終形成一個列表。

>>> contentFile = open("hello.txt")
>>> contentFile.readlines()
['How are you?\n', "I'm fine, thanks, and you?\n", "I'm fine, too."]
>>> contentFile.read()
''
>>> contentFile.seek(0)
0
>>> contentFile.read()
"How are you?\nI'm fine, thanks, and you?\nI'm fine, too."

上面的代碼中,由於先使用了readlines()方法,所以在使用read()方法時,文件指針已經到了第四行,而第四行是沒有內容的,所以read()方法返回的值為空。為了解決這個問題我們使用seed()方法,將文件指針重新指向第1行。然后在執行接下來的read()操作就可以了。

寫入文件

使用write()方法向文件中寫入新內容。當以只讀模式打開時,不能寫入新內容。以w模式打開文件寫入時會覆蓋掉文件中所有原內容,以a模式打開文件寫入時會在文件尾部插入新內容。

當打開的文件不存在時,wa模式都會新建一個文件並寫入內容。在讀取或寫入后,要調用close()方法,然后才能再次打開該文件。

>>> contentFile.close()
>>> contentFile = open("hello.txt", "a")
>>> contentFile.write("Thank you!")
10
>>> contentFile.close()
>>> contentFile = open("hello.txt")
>>> contentFile.read()
"How are you?\nI'm fine, thanks, and you?\nI'm fine, too.Thank you!"

用shelve模塊保存變量

利用shelve模塊,可以將Python程序中的變量保存到二進制的shelf文件中。這樣,程序就可以從硬盤中恢復變量的數據。shelve模塊相當於讓我們在程序中增加“保存”和“打開”功能。例如,運行一個程序,並輸入了一些配置設置,就可以將這些設置保存到一個shelf文件,然后讓程序下一次運行時加載它們。

>>> import shelve
>>> shelfFile = shelve.open("mydata")
>>> cats = ["Libai", "Dufu", 'Zhupi', 'Zhongfen']
>>> shelfFile['cats'] = cats
>>> shelfFile.close()

這個程序會在當前目錄下生成三個文件:mydata.bakmydata.datmydata.dir

>>> shelfFile = shelve.open('mydata')
>>> type(shelfFile)
<class 'shelve.DbfilenameShelf'>
>>> shelfFile['cats']
['Libai', 'Dufu', 'Zhupi', 'Zhongfen']
>>> shelfFile.close()

上面的代碼檢查了shelfFile中的內容,像字典一樣,shelf值有keys()values()方法,返回shelf中鍵和值的類似列表的值。要想使用它們,我們還要把它們轉化為列表類型:

>>> shelfFile = shelve.open('mydata')
>>> list(shelfFile.keys())
['cats']
>>> list(shelfFile.values())
[['Libai', 'Dufu', 'Zhupi', 'Zhongfen']]
>>> list(shelfFile.values())[0]
['Libai', 'Dufu', 'Zhupi', 'Zhongfen']
>>> shelfFile.close()

使用pprint.pformat()函數保存變量

pprint()是一種將列表、字典或元組以更漂亮、規范的格式輸出的一個方法。我們可以利用pprint.pformat()函數將變量寫入.py文件。該文件將成為一個模塊,方便我們下次進行使用。而且與shelve模塊中的方法不同的事,.py文件能夠方便的使用一些常見的記事本文件打開查看。例子:

>>> import pprint
>>> cats = [{'name': 'Libai', 'color': 'White'}, {'name': 'Zhupi', 'color': 'Orange'}]
>>> pprint.pformat(cats)
"[{'color': 'White', 'name': 'Libai'}, {'color': 'Orange', 'name': 'Zhupi'}]"
>>> file = open('myCats.py', 'w')
>>> file.write('cats = ' + pprint.pformat(cats) + '\n')
83
>>> file.close()
>>> import myCats
>>> myCats.cats
[{'color': 'White', 'name': 'Libai'}, {'color': 'Orange', 'name': 'Zhupi'}]
>>> myCats.cats[0]
{'color': 'White', 'name': 'Libai'}
>>> myCats.cats[0]['name']
'Libai'

值得注意的是,對於大多數的應用,我們還是利用shelve模塊來保存數據。只有基本數據類型,例如整型、浮點型、字符串、列表和字典等,可以用這個方法當做簡單文本寫入文件。

小項目一(隨機測驗試卷生成)

假如一位老師要考察班上35名同學對於美國50個州首府的了解情況,他打算用選擇題的形式來考察。但是為了防止有人作弊,他打算將題目的順序打亂且每道題目的選項中除了正確的那個,其他的都是從其他49個州的首府中隨機抽取的,那么下面的代碼會很有用:

# randomQuizGenerator.py - Create quizzes with questions and answers in random order, along with the answer key.

import random

# The quiz data. Key are states and values are their capitals.
capitals = {
    'Alabama': 'Montgomery',
    'Alaska': 'Juneau',
    'Arizona': 'Phoenix',
    'Arkansas': 'Little Rock',
    'California': 'Sacramento',
    'Colorado': 'Denver',
    'Connecticut': 'Hartford',
    'Delaware': 'Dover',
    'Florida': 'Tallahassee',
    'Georgia': 'Atlanta',
    'Hawaii': 'Honolulu',
    'Idaho': 'Boise',
    'Illinois': 'Springfield',
    'Indiana': 'Indianapolis',
    'Iowa': 'Des Monies',
    'Kansas': 'Topeka',
    'Kentucky': 'Frankfort',
    'Louisiana': 'Baton Rouge',
    'Maine': 'Augusta',
    'Maryland': 'Annapolis',
    'Massachusetts': 'Boston',
    'Michigan': 'Lansing',
    'Minnesota': 'Saint Paul',
    'Mississippi': 'Jackson',
    'Missouri': 'Jefferson City',
    'Montana': 'Helena',
    'Nebraska': 'Lincoln',
    'Nevada': 'Carson City',
    'New Hampshire': 'Concord',
    'New Jersey': 'Trenton',
    'New Mexico': 'Santa Fe',
    'New York': 'Albany',
    'North Carolina': 'Raleigh',
    'North Dakota': 'Bismarck',
    'Ohio': 'Columbus',
    'Oklahoma': 'Oklahoma City',
    'Oregon': 'Salem',
    'Pennsylvania': 'Harrisburg',
    'Rhode Island': 'Providence',
    'South Carolina': 'Columbia',
    'South Dakota': 'Pierre',
    'Tennessee': 'Nashville',
    'Texas': 'Austin',
    'Utah': 'Salt Lake City',
    'Vermont': 'Montpelier',
    'Virginia': 'Richmond',
    'Washington': 'Olympia',
    'West Virginia': 'Charleston',
    'Wisconsin': 'Madison',
    'Wyoming': 'Cheyenne'
}

# Generate 35 quiz files.
for quizNum in range(35):
    # Create the quiz and answer key files.
    quizFile = open('capitalsquiz%s.txt' % (quizNum + 1), 'w')
    answerKeyFile = open('capitalsquiz_answers%s.txt' % (quizNum + 1), 'w')

    # Write out the header for the quiz.
    quizFile.write('Name:\n\nDate:\n\nPeriod:\n\n')
    quizFile.write((' ' * 20) + 'State Capitals Quiz (Form %s)' % (quizNum + 1))
    quizFile.write('\n\n')

    # Shuffle the order of the states.
    states = list(capitals.keys())
    random.shuffle(states)

    # Loop through all 50 states, making a question for each.
    for questionNum in range(50):

        # Get right and wrong answers.
        correctAnswer = capitals[states[questionNum]]
        wrongAnswers = list(capitals.values())
        del wrongAnswers[wrongAnswers.index(correctAnswer)]
        wrongAnswers = random.sample(wrongAnswers, 3)
        answerOptions = wrongAnswers + [correctAnswer]
        random.shuffle(answerOptions)

        # Write the question and the answer options to the quiz file.
        quizFile.write('%s. What is the capital of %s?\n' % (questionNum + 1, states[questionNum]))
        for i in range(4):
            quizFile.write('%s. %s\n' % ('ABCD' [i], answerOptions[i]))
        quizFile.write('\n')

        # Write the answer key to a file.
        answerKeyFile.write('%s. %s\n' % (questionNum + 1, 'ABCD' [answerOptions.index(correctAnswer)]))
    quizFile.close()
    answerKeyFile.close()

小項目二(多重剪貼板)

這個代碼實現了一個簡單的功能,即將剪貼板中的內容以關鍵字的方式保存,而且可以以關鍵字的方式提取,相當於一個暫存(多重)剪貼板。

# mab.pyw - Saves and loads pieces of text to the clipboard.
# Usage: py.exe mcb.pyw save <keyword> - Saves clipboard to keyword.
#        py.exe mcb.pyw <keyword> - Loads keyword to clipboard.
#        py.exe mcb.pyw list - Loads all keywords to clipboard.

import shelve
import pyperclip
import sys

mcbShelf = shelve.open('mcb')

# Save clipboard content.
if len(sys.argv) == 3 and sys.argv[1].lower() == 'save':
    mcbShelf[sys.argv[2]] = pyperclip.paste()
elif len(sys.argv) == 2:
    # List keywords and load content.
    if sys.argv[1].lower() == 'list':
        pyperclip.copy(str(list(mcbShelf.keys())))
    elif sys.argv[1] in mcbShelf:
        pyperclip.copy(mcbShelf[sys.argv[1]])

mcbShelf.close()

[Python學習筆記]系列是我在學習《Python編程快速上手——讓繁瑣工作自動化(Automate The Boring Stuff With Python)》這本書時的學習筆記。通過自己再手敲一遍概念和代碼,方便自己記憶和日后查閱。如果對你有幫助,那就更好了!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM