更新於 2024/10/20閱讀時間約 4 分鐘

【💊 Python的解憂錦囊】如何將@dataclass的資料結構轉成csv並輸出

raw-image


我們在「【💊 Python的解憂錦囊】如何將dict轉成json並儲存」有介紹過如何將dict型態的資料轉換成json,除了json之外, 另一個耳熟能詳的資料交換格式就是csv了, 我們常常會將csv讀進來, 並使用預先設計的@dataclass來存放, 如此一來實際運行時, 更能夠貼近於我們開發時設計的類別,(feat.【🔒 Python 先修班】📄 請試著用dataclass來框住資料),處理完畢後我們通常也會需要將資料再轉回csv格式,以下就會說明如何進行轉換。

情境概述

那換個情境來看看, 假設我們設計了一套資料擷取系統, 專門在擷取工作人員的基本資料, 而@dataclass我們設計如下:

from dataclasses import dataclass

@dataclass
class Person:
name: str
age: int
city: str

那我們假設已經有一批擷取的資料並轉成@dataclass時…

people = [
Person('john', 18, 'taipei'),
Person('jason', 23, 'yainan'),
# ...
]

怎麼轉?

我們根據上述情境了描述可以知道, 我們已經資料了, 那接下來就是轉換成csv, 相信大家心中一定有一個疑問, 啊不就csv.writer…, 直接一筆一筆輸出嗎? 難道還有更高明的手法? 其實並沒有所謂的最高明的手法, 只有最適用的方法, 我們的情境是希望@dataclass的內容原封不動的輸出, 也就是標頭的部份就等於@dataclass的欄位, 那可以怎麼做咧?

其實我們步驟很簡單, 分成兩個部份:

  1. 如何將@dataclass的欄位轉換成headers?
  2. 如何透過csv writer輸出@dataclass的類別內容?

以下的程式碼就涵蓋了我們的疑問, 因此我們可以這樣做…

import csv

with open('./test.csv', mode='w', newline='', encoding='utf-8') as file:
headers = Person.__annotations__.keys()

# 建立輸出器並設定欄位
writer = csv.DictWriter(file, fieldnames=headers)

# 根據上述的欄位設定寫標頭
writer.writeheader()

# 將@dataclass轉換成Dict型態
rows = [person.__dict__ for person in people]

# 寫內容
writer.writerows(rows)

為什麼我們要使用DictWriter呢? 因為class本身有「dict」這個屬性, 可以轉成字典型態, 因此我們可以透過這方式來進行轉換即可。 ref: https://docs.python.org/zh-tw/3/library/stdtypes.html#object.__dict__

接著我們來看看最終的輸出吧!


結語

軟體開發的過程中,程式與資料交換格式檔案、資料庫之間常常會需要互相轉換,而為了讓開發的過程中明確的定義資料內容,我們通常會使用@dataclass來框住資料,如此一來後續維護與使用會更加的明確,當然轉換的方法不只一種,甚至也有專門的套件框架在處理這個部分,而我們僅以最小的依賴,使用內建模組來完成這樣的簡易轉換,總之方法工具都在那邊了,我們要吸收的僅是解題的邏輯,剩下的就需要靈活運用的能力囉,這樣的能力其實也不難培養,我們每天學習一點點,持續一段時間後就能夠融會貫通,加油!


學習軟體開發的路上常常苦於網路資訊爆炸嗎? 教學何其多,但卻遇到無法明確選擇的困境呢? 歡迎加入「🔒 阿Han的軟體心法實戰營」, 這裡不給您冗餘的雜訊, 單刀直入直接送您業界開發重點, 避開選擇障礙的困境, 讓您獲得業界標準的開發起手式, 成為Top 1的頂尖人才。

分享至
成為作者繼續創作的動力吧!
© 2024 vocus All rights reserved.