[Python 教學] dataclass 是什麼? (python 3.7+)

什麼是 python data classes

什麼是 dataclasses?

dataclasses 讓我們在創建 class 屬性時,可以降低屬性撰寫的重複性,且支援型別定義,和內建 __repr__(), __eq__() 一些常用的 python magic method

有興趣的朋友,可以看看 PEP 557 所提到的什麼是 dataclasses 和為什麼需要它

Why is this PEP 557 needed?
With the addition of PEP 526, Python has a concise way to specify the type of class members. This PEP leverages that syntax to provide a simple, unobtrusive way to describe Data Classes.

PEP 557 Data Classes

Python dataclasses 使用方法

1. 一個最簡單的 Dataclasses

過去我們要定義 class 的屬性時,要寫成這樣:

class Product:
    def __init__(self, name:str, qty:int):
        self.name = name
        self.qty = qty

Python 3.7 新增的 dataclasses 功能以後,我們只需要寫成像下方的 code:

from dataclasses import dataclass

@dataclass
class Product:
    name: str
    qty: int

2. __post_init__ 方法

dataclasses 被創建時,__init__() 會呼叫 __post_init__ 方法,所以你可以利用 __post_init__ 來執行在創建時你想做的事情,以下例子,可以看到 amount: int = field(init=False) 代表著在 __init__ 時不需要輸入此屬性,他會在 __post_init__ 時創建,我們利用這個方法計算出產品的總銷售額:

from dataclasses import dataclass, field

@dataclass
class Product:
    name: str
    price: int
    qty: int
    amount: int = field(init=False)

    def __post_init__(self):
        self.amount = self.price * self.qty


itemA = Product(name="itemA", price=100, qty=10)
print(itemA)

3. Python Dataclasses 搭配 DataFrame

pandas.DataFrame 可以接收 dict-like container for Series objects,所以使用上只需將 object 放在 list 裡面,然後再 df = pd.DataFrame(products),就可以搭配 pandas 使用囉

from dataclasses import dataclass
import pandas as pd

@dataclass
class Product:
    name: str
    qty: int

products = []
for i in range(10):
    products.append(Product(name=i, qty=i*2))

df = pd.DataFrame(products)

4. 增加 dataclasses methods

dataclasses 使用上就像一般的 class,所以我們也可以自己加上方法,像下面的例子,我們增加了 revenue 的方法,可以快速計算出所購買的商品總數:

from dataclasses import dataclass
from typing import List

@dataclass
class Product:
    name: str
    qty: int
    price: int

@dataclass
class Purchase:
    products: List[Product]

    def revenue(self):
        total_revenue = 0
        for product in self.products:
            total_revenue += product.qty * product.price
        return total_revenue

user_A = Purchase(
    products=[
        Product(name="item1", qty=1, price=30),
        Product(name="item1", qty=2, price=20),
        Product(name="item1", qty=3, price=10),
    ]
)

print(user_A.revenue())
>> 100

5. Immutable dataclasses

在裝飾詞上加上 frozen=True,當屬性被建立之後,就會無法被修改,變成 immutable dataclasses

關於什麼是 immutable 和 mutable 可以參考這篇:
[Python 基礎教學] 什麼是 Immutable & Mutable objects

from dataclasses import dataclass

@dataclass(frozen=True)
class Product:
    name: str
    qty: int
    price: int

itemA = Product("itemA", 10, 100)
itemA.name = "itemB"
>> dataclasses.FrozenInstanceError: cannot assign to field 'name'

那 [Python 3.7+] dataclasses 教學 結束囉,感謝收看!
如有任何問題,歡迎底下留言或私訊,我會盡快回覆您

關於 Python 物件導向教學的延伸閱讀:

▍本站的其他 object 相關教學:

▍本篇參考的文章:

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。