iT邦幫忙

2024 iThome 鐵人賽

DAY 13
0

第十一天:Python 中的文件讀寫操作

內容概述:

今天我們將學習如何在 Python 中進行文件的讀取與寫入操作。這是一個非常實用的技能,無論是處理文本檔案、記錄日誌,還是讀取 CSV 檔案,學會如何操作文件將大大提升你的程式處理能力。


一、什麼是文件操作?

  1. 文件操作的基本概念
    • 在 Python 中,我們可以透過內建的 open() 函式來打開、讀取、寫入和關閉文件。
    • 常見的操作模式有:
      • 'r':讀取模式(read),只讀取文件內容。
      • 'w':寫入模式(write),如果文件不存在,會自動創建新文件;若文件已存在,則會覆蓋原有內容。
      • 'a':追加模式(append),將新的內容加在文件末尾。
  2. 文件操作的基本流程
    • 文件操作的基本步驟為:打開文件 → 讀取/寫入 → 關閉文件。打開和關閉文件的過程中應注意文件的正確管理,避免文件未被正確關閉的情況。

二、Python 文件操作語法

  1. 打開文件

    • 使用 open() 函式打開文件:
      file = open('example.txt', 'r')  # 以讀取模式打開文件
      
  2. 讀取文件內容

    • 讀取文件的三種常見方式:
      1. 讀取整個文件
        content = file.read()
        print(content)
        
      2. 按行讀取
        for line in file:
            print(line.strip())  # 每次讀取一行,並去除行末的換行符號
        
      3. 讀取指定字元數
        part = file.read(10)  # 讀取前 10 個字元
        print(part)
        
  3. 關閉文件

    • 在操作完成後,記得使用 close() 方法來關閉文件:
      file.close()
      
  4. 使用 with 語法

    • 一種更安全的寫法是使用 with 語法,它會自動在操作結束後關閉文件:
      with open('example.txt', 'r') as file:
          content = file.read()
          print(content)
      
    • with 語法的優勢在於無需手動關閉文件,即使程式中途發生錯誤,文件也會自動關閉。

三、寫入與追加文件

  1. 寫入模式 'w'

    • 當我們想要寫入新的文件時,可以使用 'w' 模式:
      with open('output.txt', 'w') as file:
          file.write('這是新寫入的內容。\n')
      
    • 如果文件已經存在,這會覆蓋原有內容。
  2. 追加模式 'a'

    • 如果我們想要保留原有內容並在文件末尾添加新的內容,可以使用 'a' 模式:
      with open('output.txt', 'a') as file:
          file.write('這是追加的內容。\n')
      

四、讀取與寫入 CSV 文件

  1. 什麼是 CSV 文件?

    • CSV(逗號分隔值)文件是一種簡單的資料儲存格式,常用於儲存表格數據。每一行是一個數據記錄,記錄中的欄位使用逗號分隔。
  2. 讀取 CSV 文件

    • Python 提供了 csv 模組來處理 CSV 文件,以下是一個讀取 CSV 文件的範例:
      import csv
      
      with open('data.csv', 'r') as file:
          reader = csv.reader(file)
          for row in reader:
              print(row)
      
  3. 寫入 CSV 文件

    • 使用 csv.writer() 可以將資料寫入 CSV 文件:
      import csv
      
      with open('data.csv', 'w', newline='') as file:
          writer = csv.writer(file)
          writer.writerow(['Name', 'Age', 'Country'])  # 寫入表頭
          writer.writerow(['Alice', 30, 'USA'])        # 寫入數據
          writer.writerow(['Bob', 25, 'Canada'])
      

五、文件讀寫實作範例

  1. 範例 1:讀取文本文件並計算行數

    • 撰寫一個程式來讀取文件並計算文件中有多少行:
      def count_lines(file_name):
          with open(file_name, 'r') as file:
              lines = file.readlines()
              return len(lines)
      
      # 測試範例
      result = count_lines('example.txt')
      print(f'文件中有 {result} 行。')
      
  2. 範例 2:從文件中讀取並分析資料

    • 假設我們有一個 CSV 文件,包含學生的姓名和成績,我們要計算出平均成績:
      import csv
      
      def calculate_average_grade(file_name):
          with open(file_name, 'r') as file:
              reader = csv.reader(file)
              next(reader)  # 跳過表頭
              total_grade = 0
              count = 0
              for row in reader:
                  total_grade += int(row[1])  # 假設成績在第二欄
                  count += 1
              return total_grade / count if count > 0 else 0
      
      # 測試範例
      avg_grade = calculate_average_grade('students.csv')
      print(f'學生的平均成績是 {avg_grade}')
      

六、文件操作的應用場景

  1. 日誌記錄系統

    • 日誌系統通常會將運行過程中的重要事件記錄到文件中。這可以幫助開發者了解程式在運行過程中的狀態和錯誤。
  2. 資料匯入與匯出

    • 文件讀寫常用於匯入和匯出資料,例如從檔案中讀取數據來進行分析,或者將數據導出至 CSV 檔案進行分享。
  3. 讀取設定檔

    • 程式中需要根據設定檔中的參數來調整運行邏輯,這時候文件讀取就會派上用場。

七、練習與實作

練習 1:讀取文本文件
  • 寫一個程式,讀取一個文本文件並統計其中的單詞數。
練習 2:追加日誌
  • 設計一個簡單的日誌記錄系統,每次運行程式時將當前的時間和一段訊息寫入日誌文件中,並保留歷史紀錄。
練習 3:CSV 文件處理
  • 撰寫一個程式來讀取一個包含產品資料的 CSV 文件,然後計算所有產品的平均價格。

八、每日作業

  • 作業:寫一個程式來讀取一個包含學生姓名和成績的 CSV 檔案,然後根據成績進行排名並將結果寫入新的 CSV 文件中,並在程式運行時輸出前 3 名學生的姓名和成績。

提示:可以使用 sorted() 函式來對列表進行排序。


解答

這一組練習集中在檔案處理,涵蓋了文本檔案讀取、日誌系統設計以及 CSV 檔案的處理。以下是詳細的解答和程式碼範例。

練習 1:讀取文本文件並統計單詞數

def count_words_in_file(filename):
    try:
        with open(filename, 'r', encoding='utf-8') as file:
            text = file.read()
            words = text.split()
            return len(words)
    except FileNotFoundError:
        print(f"文件 {filename} 未找到。")

# 測試程式
filename = input("請輸入要讀取的文本文件名稱: ")
word_count = count_words_in_file(filename)
if word_count is not None:
    print(f"文件中的單詞數量是: {word_count}")

練習 2:追加日誌

import datetime

def append_log(message, log_filename="log.txt"):
    current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    log_entry = f"{current_time} - {message}\n"
    with open(log_filename, 'a', encoding='utf-8') as log_file:
        log_file.write(log_entry)
    print("日誌已記錄。")

# 測試程式
message = input("請輸入要記錄的訊息: ")
append_log(message)

練習 3:CSV 文件處理(計算平均價格)

import csv

def calculate_average_price(filename):
    total_price = 0
    count = 0
    try:
        with open(filename, newline='', encoding='utf-8') as csvfile:
            reader = csv.DictReader(csvfile)
            for row in reader:
                total_price += float(row['價格'])
                count += 1
        return total_price / count if count > 0 else 0
    except FileNotFoundError:
        print(f"文件 {filename} 未找到。")
    except KeyError:
        print("CSV 文件中找不到 '價格' 欄位。")

# 測試程式
csv_filename = input("請輸入產品資料的 CSV 文件名稱: ")
average_price = calculate_average_price(csv_filename)
if average_price:
    print(f"產品的平均價格是: {average_price:.2f}")

每日作業:讀取學生成績的 CSV 文件並排名

import csv

def rank_students(input_filename, output_filename):
    try:
        with open(input_filename, newline='', encoding='utf-8') as csvfile:
            reader = csv.DictReader(csvfile)
            students = list(reader)
        
        # 根據成績排序
        students_sorted = sorted(students, key=lambda x: float(x['成績']), reverse=True)
        
        # 將排名結果寫入新的 CSV 文件
        with open(output_filename, 'w', newline='', encoding='utf-8') as csvfile:
            fieldnames = ['姓名', '成績']
            writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
            writer.writeheader()
            writer.writerows(students_sorted)
        
        # 輸出前 3 名的學生姓名和成績
        top_students = students_sorted[:3]
        print("前 3 名的學生: ")
        for student in top_students:
            print(f"{student['姓名']}: {student['成績']}")
    
    except FileNotFoundError:
        print(f"文件 {input_filename} 未找到。")
    except KeyError:
        print("CSV 文件中找不到 '姓名' 或 '成績' 欄位。")

# 測試程式
input_csv = input("請輸入學生成績的 CSV 文件名稱: ")
output_csv = "student_ranking.csv"
rank_students(input_csv, output_csv)

解釋:

  1. 練習 1:我們讀取文本文件,並將文本中的單詞分割為列表,再計算列表中的單詞數量來得到統計結果。

  2. 練習 2:這個簡單的日誌系統使用 datetime 模組獲取當前時間,並將訊息與時間戳記追加到日誌文件中。

  3. 練習 3:處理 CSV 文件,我們利用 csv.DictReader 來讀取 CSV 文件的資料,並計算所有產品的平均價格。

  4. 每日作業:讀取學生名單,根據成績進行排序,並將結果寫入新的 CSV 文件中,同時輸出排名前 3 名的學生姓名與成績。


透過今天的學習,你將掌握如何進行文件的基本操作,並學會讀取和寫入 CSV 檔案,這是日常開發中非常實用的技能。

明日課程預告:將學習「物件導向程式設計:類別與物件的基礎概念」。


上一篇
從 0 開始學!跟著 ChatGPT 學會 Python 資料結構基礎—集合(Set)
下一篇
從 0 開始學!跟著 ChatGPT 學會 Python 物件導向程式設計(OOP)基礎
系列文
如果讓chatgpt參加iThome鐵人賽,他竟然寫出...!?31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言