- จากเทรนด์ล่าสุดของ การพัฒนา AI จึงเริ่มเรียนรู้และใช้งาน Python อย่างจริงจัง และตอนนี้รู้สึกพึงพอใจกับระบบนิเวศของมันอย่างมาก
- Python ได้พัฒนาจนกลายเป็นภาษาที่ เร็วและทันสมัย กว่าในอดีตมาก และสัมผัสได้ถึงความก้าวหน้าอย่างรวดเร็ว เช่น การเพิ่มประสิทธิภาพผ่าน Cython
- นำ เครื่องมือและไลบรารีสมัยใหม่ อย่าง uv, ruff, pytest, Pydantic มาใช้ในเวิร์กโฟลว์ของตนอย่างแข็งขันเพื่อเพิ่มผลิตภาพในการพัฒนา
- นำโครงสร้างโปรเจกต์และแนวทางอัตโนมัติมาใช้เพื่อลดความต่างระหว่าง สภาพแวดล้อมโปรดักชัน กับการพัฒนาแบบ Jupyter notebook/สคริปต์
- ใช้ GitHub Actions, Docker ฯลฯ เพื่อสร้าง CI/CD, การทดสอบ, และการจัดการโครงสร้างพื้นฐาน ได้อย่างมีประสิทธิภาพ
สรุป I’m Switching to Python and Actually Liking It
ทำไมจึงเปลี่ยนมาทาง Python
- ในสภาพแวดล้อมการพัฒนาที่มี AI เป็นศูนย์กลาง Python ได้กลายเป็น ภาษามาตรฐานโดยพฤตินัย ไปแล้ว
- เดิมทีเคยใช้แค่สำหรับเขียนสคริปต์ง่าย ๆ แต่ช่วงหลังเริ่มใช้อย่างจริงจังเพื่อสร้าง “แอปที่ใช้งานจริง” เช่น RAG, เอเจนต์, และ generative AI
- ระหว่างทางนั้นทำให้รู้สึกได้ว่าระบบนิเวศของ Python พัฒนาไปไกลมากเมื่อเทียบกับอดีต
จุดแข็ง 3 ข้อของ Python
- ระบบนิเวศของไลบรารีและเครื่องมือที่อุดมสมบูรณ์: เด่นด้านการประมวลผลข้อมูล การวิเคราะห์ เว็บ และ AI
- ประสิทธิภาพที่ดีขึ้นจาก Cython และอื่น ๆ: สามารถทำ optimization แบบคอมไพล์ได้
- ความอ่านง่ายของไวยากรณ์ที่ดีขึ้น: ไวยากรณ์แบบ legacy อย่าง
__init__, __new__ ถูกซ่อนไว้มากขึ้น และมีไวยากรณ์ที่ใช้งานได้ตรงไปตรงมามากกว่าเดิม
โครงสร้างโปรเจกต์ (แบบ Monorepo)
เครื่องมือและการตั้งค่าหลัก
-
uv
- ตัวจัดการแพ็กเกจ Python และเครื่องมือ build สมัยใหม่ จาก Astral
- จัดการงานส่วนใหญ่ได้อย่างรวดเร็ว ไม่ว่าจะเป็นการจัดการ dependency การสร้าง virtual environment หรือการตั้งต้นโปรเจกต์
pyproject.toml คือไฟล์ตั้งค่าหลักที่รวม metadata และข้อมูล dependency ทั้งหมดไว้
- สามารถตั้งค่าสภาพแวดล้อมโปรเจกต์ได้อย่างรวดเร็วด้วยคำสั่ง
uv init, uv add, uv sync
-
ruff
- linter และ code formatter สำหรับ Python ที่เร็วมาก
- เป็นเครื่องมือที่รวม
isort, flake8, autoflake และอื่น ๆ เข้าไว้ด้วยกัน
- ใช้
ruff check, ruff format สำหรับ linting และแก้ไขอัตโนมัติ
- รองรับแนวทางการเขียนโค้ดตาม PEP 8 โดยพื้นฐาน
-
ty
- static type checker สำหรับ Python ที่สร้างโดย Astral
- เมื่อใช้ร่วมกับ
typing จะช่วยด้าน static analysis และป้องกันบั๊กได้ตั้งแต่ต้น
- แม้อยู่ในช่วงเริ่มต้นของการพัฒนา แต่ก็อยู่ในระดับที่ใช้งานได้อย่างเสถียร
-
pytest
- เฟรมเวิร์กทดสอบ Python ยอดนิยม ที่รองรับ unit test และสภาพแวดล้อมการทดสอบที่ขยายได้
- ใช้กฎการตั้งชื่อไฟล์แบบง่ายและคำสั่งเพียงบรรทัดเดียวก็รวมการทดสอบได้ทันที
- ตั้งชุดทดสอบเป็น
test_*.py แล้วรันด้วย uv run pytest
- ไวยากรณ์กระชับ และมีระบบนิเวศของปลั๊กอินที่หลากหลาย
-
Pydantic
- ไลบรารีสำหรับตรวจสอบข้อมูลและจัดการการตั้งค่าสภาพแวดล้อม
- โหลดค่าตั้งค่าจากตัวแปรสภาพแวดล้อมใน
.env พร้อมตรวจสอบชนิดข้อมูล
- ใช้คลาส
BaseSettings เพื่อจัดการ API key หรือ DB URL ได้อย่างปลอดภัย
-
MkDocs
- ช่วยให้ การสร้างเว็บไซต์แบบสแตติกและเอกสารของโปรเจกต์ Python ทำได้ง่าย
- สามารถนำดีไซน์สวยแบบสไตล์โอเพนซอร์สโปรเจกต์มาใช้ได้อย่างรวดเร็ว
- เชื่อมต่อกับ GitHub Pages ได้ง่ายด้วย
-
FastAPI
- เฟรมเวิร์กสำหรับสร้าง RESTful API ที่รวดเร็ว
- มีข้อดีด้านการตรวจสอบอัตโนมัติ การสร้างเอกสารอัตโนมัติ ประสิทธิภาพสูง และผสานกับ Pydantic ได้ง่าย
- สร้างบน Starlette และ Pydantic จึงให้ทั้ง type safety และประสิทธิภาพที่ดี
-
Dataclasses
- ฟีเจอร์มาตรฐานของ Python ที่ช่วยให้ นิยามคลาสแบบเน้นข้อมูล ได้อย่างง่ายดาย
- สร้างเมธอดพิเศษให้อัตโนมัติ ช่วยลดโค้ด boilerplate ได้มาก
การจัดการเวอร์ชันและระบบอัตโนมัติ
-
GitHub Actions
- จัด CI pipeline แยกกัน สำหรับ
project-api และ project-ui
- มีเวิร์กโฟลว์ที่เหมาะกับการสร้าง CI pipeline บนหลายระบบปฏิบัติการ
- สามารถทดสอบใน สภาพแวดล้อมเดียวกับโปรดักชัน ได้ผ่านสภาพแวดล้อมทดสอบแบบ Docker
-
Dependabot
- ทำ การอัปเดต dependency อัตโนมัติ และจัดการ security patch แบบอัตโนมัติ
-
Gitleaks
- เครื่องมือสำหรับ ป้องกันการรั่วไหลของข้อมูลสำคัญ (เช่น รหัสผ่าน, API key) โดยตรวจสอบความปลอดภัยก่อน git commit
-
Pre-commit Hooks
- เครื่องมือสำหรับ linting, formatting และตรวจสอบความปลอดภัยอัตโนมัติก่อน commit
- ใช้ร่วมกับ ruff, gitleaks ฯลฯ เพื่อคงความสม่ำเสมอและคุณภาพของโค้ด
ระบบอัตโนมัติด้านโครงสร้างพื้นฐาน
-
Make
- รองรับเวิร์กโฟลว์การพัฒนาที่สม่ำเสมอด้วยคำสั่งอย่าง
make test, make infrastructure-up
- มี Makefile แยกอยู่ทั้งที่ root ของโปรเจกต์และใน
project-api
-
Docker & Docker Compose
- แยกรัน
project-api และ project-ui เป็นคนละคอนเทนเนอร์
- สามารถรันทั้งแอปได้ด้วยบรรทัดเดียว
docker compose up --build -d
- ใน
Dockerfile มีการติดตั้ง uv และคำสั่งรันแอป FastAPI
สรุปท้ายเรื่อง
- อย่างที่กล่าวไป สภาพแวดล้อมการพัฒนา Python ยุคใหม่สามารถสร้างเวิร์กโฟลว์ระดับโปรดักชันที่มีทั้งประสิทธิภาพและความแข็งแรงได้
- สามารถได้รับประโยชน์มากมายจากการเติบโตของระบบนิเวศ Python และการพัฒนาของเครื่องมือต่าง ๆ ในหลายด้าน เช่น AI, ข้อมูล และเว็บ
- ตั้งแต่โครงสร้าง monorepo เครื่องมืออัตโนมัติ linter และ type checker สภาพแวดล้อมทดสอบที่พร้อมใช้งานทันที การทำเอกสาร ไปจนถึงการ orchestration โครงสร้างพื้นฐาน ล้วนรวมกันเป็นวัฒนธรรมการพัฒนาแบบบูรณาการเดียวได้
6 ความคิดเห็น
กำลังเปลี่ยนมาใช้ Python และชอบมันมากกว่าที่คิดไว้
ข้อเสียของ Python คือแม้จะมีไลบรารีและเฟรมเวิร์กที่อุดมสมบูรณ์ แต่การจัดการเวอร์ชันของแพ็กเกจทำได้ไม่ค่อยดีและมักเกิดการชนกันบ่อย
แนวโน้มของข้อดีข้อเสียคล้ายกับ Java ในอดีต
uvที่พูดถึงในเนื้อหาก็เป็นของจริงเลยครับ เร็วก็เร็วมาก แถมยังจัดการเวอร์ชันกับ dependency ได้ดีเหมือนnpmเลย ตอนนี้เลยกำลังปักหลักใช้uvอยู่ครับแต่ช่วงนี้ดูเหมือนว่าปัญหาเรื่องการจัดการเวอร์ชันและการชนกันของแพ็กเกจส่วนใหญ่ได้รับการแก้ไขแล้วผ่าน uv กับ poetry
เหมาะสมพอที่จะครอบคลุมอีโคซิสเต็มไปจนถึง React และส่วนต่าง ๆ แบบนี้ด้วยไหม?
แม้การเชื่อมต่อกับ React โดยตรงจะมีส่วนที่ยากอยู่บ้างเพราะเป็นคนละภาษา แต่ก็ดูเหมือนว่าจะมีส่วนที่ทำได้ขึ้นอยู่กับว่าคุณต้องการอะไร
โดยส่วนตัวแล้ว ผมคิดว่าการพัฒนาฟรอนต์เอนด์ด้วย Python ยังไม่ค่อยเป็นที่แพร่หลายมากนัก
ความคิดเห็นจาก Hacker News
วิธีแสดงข้อความแบบ OR ว่า “ไม่มี YOUTUBE_API_KEY หรือ YOUTUBE_CHANNEL_ID” เมื่อ environment variable หายจากโค้ดนั้นเป็นการทำให้ผู้ใช้ลำบากโดยไม่จำเป็นในกรณีที่ไม่จำเป็นต้องใช้ OR ควรตรวจแต่ละค่าแยกกันแล้วบอกให้ชัดเจนว่าขาดตัวไหน จะเป็นประสบการณ์ใช้งานที่ดีกว่ามาก และแทบไม่ต่างกันในแง่เวลาเขียนโค้ด จึงแนะนำให้ทำแบบนั้น
แม้จะเป็นการจู้จี้กับรายละเอียดเล็กน้อย แต่ผมคิดว่ากรณีแบบนี้เหมาะมากกับการใช้ตัวดำเนินการ := (walrus operator) เช่น
if not (API_KEY := os.getenv("API_KEY")):สามารถเขียนได้ตรงนั้นเลย ส่วนตัวแล้วใน internal tool ผมมักปล่อยให้os.environ["API_KEY"]โยนKeyErrorออกมาตรง ๆ ซึ่งผมก็คิดว่าชัดเจนพอแล้วเหมือนกันไปไกลกว่านั้น ผมคิดว่าควรตรวจเงื่อนไขทีละตัว และถ้ามีตัวไหนขาดก็ควรบอกทั้งหมดในครั้งเดียว จะดีกว่ามาก เพราะช่วยลดความน่ารำคาญจากการรันโปรแกรมแล้วเจอว่าขาดตัวแปรหนึ่ง จากนั้นพอแก้แล้วก็มาเจออีกตัวหนึ่ง แม้บางสถานการณ์จะเลี่ยงความยุ่งยากไม่ได้ แต่ถ้าทำได้ก็ควรแสดงให้ครบในครั้งเดียว
วิธีที่ดีที่สุดคือดึง environment variable ทั้งหมดมาก่อน แล้วรายงานตัวที่ขาดทั้งหมดในทีเดียว
อีกวิธีคือใช้ boolean flag แล้วค่อย
exit(1)แค่ครั้งเดียวตอนท้าย แบบนี้จะแสดง environment variable ที่ขาดทั้งหมดได้ในครั้งเดียวจะใช้
exit("Missing ...")เพื่อพิมพ์ข้อความแล้วจบด้วยโค้ด 1 ทันทีเลยก็ได้ถ้ากำลังหาตัวช่วยสร้างโครงสร้างโปรเจกต์อัตโนมัติ ขอแนะนำ cookiecutter ผมมีเทมเพลตที่ใช้บ่อยอยู่หลายตัว เช่น python-lib, click-app, datasette-plugin, llm-plugin ใช้งานได้แบบนี้:
uvx cookiecutter gh:simonw/python-libผมทำตัวหนึ่งใน Ruby ชื่อ baker ขึ้นมา baker ไม่ได้คัดลอก template repo แต่จะสร้างรายการงานที่ต้องทำออกมาแทน เป็นรายการขั้นตอนเชิงคำสั่ง และสามารถผสมงานที่ต้องทำเองด้วยมือ เช่น ไปเอา API key มาตั้งค่า กับงานอัตโนมัติอย่าง
uv initได้ ใช้ Markdown syntax ร่วมกับ Ruby string interpolation และ bash ได้ด้วย ที่ทำขึ้นมาก็เพราะเบื่อ config แบบ yml มากจริง ๆอีกตัวที่กำลังมาแรงช่วงนี้คือ Copier ดูรายละเอียดได้ที่ เอกสารของ copier
ผมกลับเป็นคนที่สนุกกับการตั้งค่าโปรเจกต์ใหม่เอง เลยไม่ค่อยอยากทำสิ่งพวกนี้ให้เป็นอัตโนมัติ
ผมคิดว่าเครื่องมืออัตโนมัติสำหรับจัดโครงสร้างแบบนี้จริง ๆ แล้วเหมาะมากกับเวิร์กโฟลว์การพัฒนาแบบ agent-based LLM ในยุคนี้ด้วย
คำบอกว่า "Python เป็นมิตรกับมนุษย์มากกว่าเพราะมากับ Unix ส่วนใหญ่เป็นค่าเริ่มต้น" นั้นค่อนข้างมองโลกสวยไปหน่อย พอเกินระดับ
import jsonไปแล้ว ก็จะตกสู่นรก virtualenv อย่างรวดเร็ว ถ้าจะให้รันบน Python 3.13.x ใน Ubuntu 22.04 หรือ 24.04, Rocky 9 และระบบอื่น ๆ ได้ สุดท้ายก็เลี่ยงvenv, container หรือ version manager ไม่พ้นแม้แต่ไลบรารีพื้นฐานอย่าง “import json” ถ้าเป็นภาษาอื่นที่ไม่มีมาให้ก็อาจต้องติดตั้งเพิ่ม แต่ Python มี standard library ที่ช่วยให้เริ่มต้นได้เร็ว แน่นอนว่าสำหรับโปรเจกต์ใหญ่ standard library อย่างเดียวไม่พอ แต่ในทางปฏิบัติผมก็เคยปล่อยโค้ดใช้งานจริงหลายตัวด้วย standard library ล้วน ๆ และไม่เจอปัญหาเรื่อง deployment หรือการจัดการความปลอดภัย ส่วนการดูแล
venvก็ไม่ได้ยากเหมือนเมื่อก่อนแล้ว และ package manager ก็พัฒนาขึ้นมากผมมีทฤษฎีติดตลกอยู่อย่างหนึ่งว่า เหตุผลครึ่งหนึ่งที่ Docker/container แพร่หลายเร็วขนาดนี้ ก็เพราะมันช่วยให้คนหนีพ้นจาก dependency hell ของ Python ประสบการณ์แรกของผมกับ Python คือการติดตั้ง service บนเซิร์ฟเวอร์เมื่อปี 2012 ทั้ง dependency hell, คำสั่ง
venv, การตั้งค่าสภาพแวดล้อมที่จัดการยาก มันแย่มาก ผมลองผิดลองถูกกับ pip, brew, และสภาพแวดล้อมบน macOS อยู่ตลอด จนเห็น Python แล้วอยากหลบ แต่พักหลังมานี้ด้วย uv ทำให้รู้สึกว่า Python ดีขึ้นมากแม้มองจากมุมมือใหม่ แค่uv init,uv add,uv runก็พอแล้วผมคิดว่าควรใช้
virtualenvตลอดอยู่แล้ว สุดท้ายมันก็แค่ไดเรกทอรีหนึ่งเท่านั้น และตอนนี้ถ้าจะติดตั้งด้วย pip แบบทั้งระบบก็ยังมีคำเตือนขึ้นมาแล้ว จึงไม่ได้ยากเหมือนแต่ก่อนควรใช้
virtualenvหรือ container อยู่แล้ว แม้จะรู้สึกว่ายุ่งยาก แต่ก็ช่วยหลีกเลี่ยงผลกระทบกับทั้งระบบจากการอัปเดตหรือการอัปเวอร์ชันไลบรารีได้เมื่อก่อนหลายระบบมีเพียง Python2 ติดมากับระบบ และบางครั้งตัวระบบเองก็พึ่ง Python2 นี้อยู่ด้วย เลยยิ่งเสี่ยงกว่าเดิม
ผมรู้สึกว่า Python ทั้งเยิ่นเย้อและยังไม่พอในเวลาเดียวกัน ถ้าจะทำอะไรสักอย่างง่าย ๆ ก็ต้องใส่ dependency เป็นร้อย หรือไม่ก็ต้องเขียนโค้ดตั้งแต่หลายสิบไปจนถึงเป็นร้อยบรรทัดแม้จะเป็นเรื่องเล็กน้อย เลยหลีกเลี่ยง Python เพราะมีงานจุกจิกที่ไม่จำเป็นเยอะเกินไป ผมชอบ Perl มากกว่าเพราะทำงานให้เสร็จได้เร็วและกระชับกว่ามาก Python ดูเหมือนเป็นการเขียนโปรแกรมเพื่อการเขียนโปรแกรม มากกว่าจะเป็นการทำงานให้เสร็จ
ผมก็ทำโปรเจกต์ที่ไม่มี dependency อยู่เยอะเหมือนกัน ใช้แค่ standard library กับไฟล์เดียวก็ทำอะไรได้มากจริง ๆ ถ้ามี Python ติดตั้งอยู่ก็
curlลงมารันได้เลย เช่นมี CLI tool จัดการเงินตัวหนึ่งยาว 2000 บรรทัดคือ plutus ซึ่งใช้ standard module แค่ประมาณ 12 ตัวเอง และราว 25% ของโค้ดก็เป็นส่วน parse คำสั่งด้วยargparseผมชอบเขียนให้ชัดเจนแบบวางหนึ่งบรรทัดต่อหนึ่งพารามิเตอร์คุณบอกว่า Perl เร็วกว่าและทรงพลังมากกว่า Python อยากรู้ว่ามีตัวอย่างที่ชัดเจนไหม
จุดที่ Python สะดวกคือเวลาซ้อน data structure ไม่ต้องคิดมาก ใช้ list ที่มี tuple, dictionary หรือแบบผสมกันได้อย่างอิสระ และเข้าถึงได้ด้วย syntax ที่สม่ำเสมอ Perl แน่นอนว่าฉลาดกว่าและสนุกกว่า แต่เพราะแบบนั้นแหละมันเลยทำให้หัวพันง่ายสำหรับผม Python อาจจะน่าเบื่อกว่า แต่มีความชัดเจนสูงมากจนอีก 5 ปีผ่านไปก็ยังกลับมาอ่านแล้วเข้าใจได้
ผมคิดว่า Python ใช้ได้ดีพอแม้พึ่งแค่ standard library
ผมเป็นพวกชอบโครงสร้าง monorepo แต่ที่บริษัทเก่าเคยมีกรณีที่แนวทางนี้ทำให้เกิดโครงสร้างขนาดมหึมาและเทอะทะ จนไม่มีใครกล้าแตะโค้ดของทีมอื่นเพราะกลัวพัง ประเด็นหลักจริง ๆ ไม่ใช่ตัว repo เอง แต่เป็นเพราะจัดการ
requirements.txtชุดเดียวทั้ง repo หรือมี build script ที่พันกันยุ่ง ในทางทฤษฎี ถ้าอัปเดต dependency ครั้งเดียว ทุกโค้ดก็ควรปลอดภัยจากแพตช์ล่าสุด แต่ในโลกจริงกลับไม่มีใครกล้ายุ่งกับมัน Monorepo จะเวิร์กก็ต่อเมื่อองค์กรมีความเป็น NIH สูงมากเท่านั้น คือมีแนวโน้มทำทุกอย่างเองเหมือน Google ประสบการณ์นี้ทำให้ผมเริ่มมองโครงสร้าง microservice ที่แต่ละ service สอดคล้องกับโครงสร้างทีมในองค์กรในแง่บวกมากขึ้น ดู Conway's law เพิ่มได้Python เป็นภาษาที่ทำงานใกล้กับ pseudocode ที่ผมเขียนที่สุด ทุกจุดที่ผมคิดเอาเองในหัวว่ามันควรชัดเจน Python ก็มักมี abstraction ที่ตรงไปตรงมาให้จริง ๆ ผมมาจากพื้นฐานด้านคณิตศาสตร์เลยรู้สึกประทับใจมาก แน่นอนว่าตอนนี้ก็ชอบภาษาอื่นด้วย แต่ Python ก็ยังมีเสน่ห์อยู่
ผมจัดโครงโปรเจกต์ด้วยแพตเทิร์นแทบเหมือนกันเป๊ะ มันคล้ายกันจนน่าขนลุก เลยเริ่มคิดว่า ecosystem ของนักพัฒนา Python กำลังค่อย ๆ ลู่เข้าหาสไตล์เดียวกันหรือเปล่า เมื่อก่อนผมคิดว่าตัวเองเลือกอะไรที่มีเอกลักษณ์ แต่พอเห็นว่าทุกคนทำคล้ายกัน ก็เริ่มสงสัยว่าเจตจำนงเสรีของผมหายไปไหน มันเหมือนกับปรากฏการณ์ตั้งชื่อลูก ที่ตัวเลือกซึ่งคิดว่าไม่เหมือนใคร จริง ๆ แล้วกลับเป็นชื่อยอดนิยมอันดับ 2
โครงสร้างแบบนี้เป็นที่นิยมใน Python มาตั้งแต่ 10 ปีก่อนแล้ว สุดท้ายแล้วดูเหมือนว่าวิศวกรที่ใช้เหตุผลหลายคน เมื่อคิดอย่างรอบคอบก็จะค่อย ๆ มารวมตัวกันที่แพตเทิร์นนี้เองตามธรรมชาติ
รู้สึกเหมือนอีโก้ของมนุษย์แผ่คลุมทุกสเปกตรัมเหมือน pilot-wave quantum wave แล้วค่อยเปลี่ยนเป็นการดำรงอยู่ becoming-being ชวนขำจริง ๆ
รู้สึกดีใจที่เห็นคนอื่นเริ่มชอบ Python เหมือนกัน เดิมทีผมชอบ Ruby มากกว่า แต่เพราะความต้องการของลูกค้าเลยจำใจต้องใช้ Python เมื่อก่อน Ruby ช้ามาก แต่พอถูกบังคับให้เรียน Python ก็เริ่มคุ้นขึ้นเรื่อย ๆ และตอนนี้ก็สนุกกับมันในแบบของตัวเอง ส่วนเรื่องการใช้ Make ผมเห็นต่างนิดหน่อย ถ้าไม่มี dependency เลย มันก็แทบไม่ต่างจากสคริปต์ที่มี
casestatement... พูดขำ ๆ ครึ่งหนึ่ง แต่ก็อดเศร้าไม่ได้ที่คนรุ่นนี้ไม่ค่อยคุ้นกับ Make ความรู้สึกแบบ “สมัยฉันน่ะนะ” เลยRuby มี syntax ที่สวยกว่ามาก การแบ่งขอบเขตด้วยการเยื้องบรรทัดอย่างเดียวใน Python ไม่ใช่สไตล์ของผม
ตอนแรกผมเริ่มจากสคริปต์ที่มี
casestatement แต่สุดท้ายมันค่อย ๆ วิวัฒน์เป็น Makefile แบบแบน ๆ Makefile มาตรฐานกว่าและอ่านเข้าใจง่ายกว่าสคริปต์สุ่ม ๆสงสัยว่าควรใช้ Dataclass หรือ Pydantic Basemodel มากกว่ากัน ถ้าใช้ Pydantic อยู่แล้ว ก็น่าจะรวมทุกอย่างไปทาง Pydantic เลยได้หรือเปล่า เลยลังเลว่ายังมีเหตุผลอะไรให้ใช้ Dataclass อยู่ไหม
ฝั่งโปรเจกต์ attrs มีบทความเปรียบเทียบที่สรุปไว้ดีมาก มี บทเปรียบเทียบอย่างเป็นทางการของ attrs ซึ่งแน่นอนว่าอาจมีอคติอยู่บ้าง แต่ผมคิดว่ามีเหตุผลรองรับเชิงตรรกะเพียงพอ และ บล็อกนี้ ก็มีประโยชน์เช่นกัน
Dataclass ไม่รองรับการตรวจสอบ nested object ดังนั้นถ้าเป็นโครงสร้างแบบแบน ๆ สำหรับส่งผ่านอาร์กิวเมนต์ของฟังก์ชัน การใช้ dataclass จะเหมาะกว่า และก็ชัดเจนกว่าการรับอาร์กิวเมนต์จำนวนมากเป็น list
การตรวจสอบข้อมูลตอนสร้างมีผลด้านประสิทธิภาพด้วย และก็มีทางเลือกที่เบาและเร็วกว่าอย่าง msgspec
ถ้าไม่ได้ต้องการ validation หรือ serialization จริง ๆ Pydantic จะกลายเป็น overhead ที่ไม่จำเป็น หลักของผมคือ ถ้าต้อง serialization ใช้ Pydantic ไม่งั้นใช้ dataclass
สามารถใช้ dataclass เดิมได้ตรง ๆ ผ่าน
TypeAdapter(MyDataclass)อยู่แล้ว เลยไม่แน่ใจว่าทำไมต้องสร้าง Pydantic model แยกต่างหากช่วงหลัง ๆ ผมกลับย้ายออกจาก Python ไปใช้ภาษาอื่นแล้วพอใจกว่า ความเห็นของผมเกี่ยวกับ Python เขียนไว้ใน บทความนี้ ถ้าครั้งหน้ามีโอกาสกลับมาใช้ Python อีก ผมตั้งใจว่าจะลองใช้ uv, ruff, ty ให้ครบ