งูต้นฉบับกำลังประกอบบัตรข้อมูลจากช่องฟิลด์ แล้วล็อกกรอบคลาสให้แก้ค่าไม่ได้

Python 3.14 make_dataclass decorator: กำหนด policy ตอนสร้างคลาสจาก schema

พี่โชว์Engineering

ระบบที่รับ schema จาก config อาจต้องสร้างคลาสข้อมูลตอน runtime Python 3.14 เพิ่ม decorator= ให้ make_dataclass เพื่อส่งคลาสที่สร้างไปผ่าน policy ของเรา เช่น บังคับ frozen และ slots ทุกครั้งครับ

from __future__ import annotations

import unittest
from dataclasses import FrozenInstanceError, dataclass, make_dataclass


def frozen_slots(cls, **kwargs):
    kwargs["frozen"] = True
    kwargs["slots"] = True
    return dataclass(cls, **kwargs)


Job = make_dataclass(
    "Job",
    [("name", str), ("retries", int, 0)],
    decorator=frozen_slots,
)


class MakeDataclassTests(unittest.TestCase):
    def test_policy_is_applied(self) -> None:
        job = Job("backup")
        self.assertEqual(job.retries, 0)
        with self.assertRaises(FrozenInstanceError):
            job.retries = 1


if __name__ == "__main__":
    unittest.main()

Hook นี้เหมือนด่านมาตรฐานโรงงาน ต่อให้ schema เปลี่ยน รุ่นสินค้าทุกชิ้นยังต้องผ่านกติกาเดียวกัน แต่ dynamic class มีราคาด้านการค้นหาโค้ดและ type checking ถ้า schema รู้ตอนเขียนโปรแกรม ให้ประกาศ @dataclass ปกติจะอ่านง่ายกว่า

อย่าส่ง field จาก input ที่ไม่เชื่อถือโดยตรง ต้อง allowlist ชื่อและชนิด ป้องกันชื่อชน attribute สำคัญ และจำกัดจำนวน field ส่วน decorator ควร deterministic และไม่มี network/side effect เพราะมันรันตอนสร้างคลาส

Recap

  • ใช้ decorator= เพื่อรวม policy ของ dynamic dataclass
  • เลือก static dataclass เมื่อ schema รู้ล่วงหน้า
  • validate ชื่อ ชนิด และจำนวน field จาก input
  • ทดสอบ policy เช่น frozen, slots และ repr