fieldenum: รองรับ enum แบบมีฟิลด์สไตล์ Rust ใน Python
(github.com/ilotoki0804)- fieldenum คือ enum ที่มีค่าอยู่ภายใน (และสามารถสร้างอินสแตนซ์ได้)
- รองรับ enum แบบมีฟิลด์ของ Rust ได้อย่างเรียบร้อย
- พยายามสร้างสมดุลระหว่างความบริสุทธิ์ของการเขียนโปรแกรมเชิงฟังก์ชันกับความใช้งานได้จริงใน Python
- รองรับ
Optionซึ่งเป็นทางเลือกแทนNoneและBoundResultซึ่งเป็นทางเลือกแทนข้อยกเว้นโดยค่าเริ่มต้น - มีการทดสอบอย่างครบถ้วน
- ตอนนี้เอกสารภาษาอังกฤษยังค่อนข้างน้อย แต่มีแผนจะค่อย ๆ เติมให้ครบ
- ยินดีต้อนรับการสนับสนุนทุกรูปแบบ ไม่ว่าจะเป็น issue, PR, star เป็นต้น
14 ความคิดเห็น
ผมคิดว่า union type ของ dataclass อาจจะดีกว่า แต่ยกเว้นแค่ตรงที่ประกาศสั้นกว่าแล้ว ก็ยังไม่ค่อยเห็นข้อดีนักครับ มีจุดไหนที่ fieldenum ดีกว่าอย่างชัดเจนเป็นพิเศษไหม?
จุดเด่นอย่างหนึ่งคือการประกาศที่สั้น กระชับ และมีเฉพาะส่วนที่จำเป็น
ตัวอย่างเช่น
หากจะนำ
fieldenumข้างต้นไปเขียนด้วยdataclassจะต้องเขียนแบบนี้โค้ดยาวขึ้น มองก็ยากขึ้น โอกาสพลาดก็สูงขึ้น และคงไม่รู้สึกว่าโค้ดดูสะอาดตาใช่ไหม
แน่นอนว่าต่อให้เขียนแบบนี้ ก็ยังไม่สามารถได้ฟีเจอร์อื่น ๆ ที่
fieldenumมีให้ (generics, repr,__fields__, ...)ดังนั้นหากมี
fieldenumที่รวบรวมและจัดการสิ่งเหล่านี้ไว้ทั้งหมด ก็จะสะดวกกว่ามากนอกจากนี้ยังแนะนำให้ลองดูเนื้อหาในส่วน
ตัวอย่างเพิ่มเติมด้วยdataclassรองรับการทำreprโดยค่าเริ่มต้นdataclasses.fieldsให้ข้อมูลรันไทม์เกี่ยวกับการนิยามฟิลด์typingตั้งแต่ 3.5 และ syntactic sugar รองรับตั้งแต่ 3.12Messagesสามารถทำเป็นโมดูลได้ถึงอย่างนั้น การไม่มีโค้ด boilerplate ที่จำเป็นสำหรับการนิยาม class และการสามารถใช้ enum กับ class ผ่านอินเทอร์เฟซเดียวกันได้ ก็อาจเป็นข้อดีอยู่เหมือนกันนะครับ ขอบคุณสำหรับคำอธิบายละเอียด ๆ
https://stackoverflow.com/a/47784683
ก่อนหน้านี้ก็มีความพยายามหลายแบบในการแสดงโครงสร้างข้อมูลในลักษณะนี้ แต่ท้ายที่สุดก็ดูเหมือนจะเป็นทั้งข้อจำกัดและจุดอ่อนของ Python เอง ผมเคยรู้จัก ADT (algebraic data type) ครั้งแรกตอนเรียนในมหาวิทยาลัยผ่าน OCaml แต่พอเวลาทำงานจริงกลับต้องทำได้แค่เลียนแบบในลักษณะนี้ ก็แอบน่าเสียดายอยู่เหมือนกัน
ไลบรารีที่ ilotoki สร้างขึ้นน่าจะถือเป็นกรณีที่เข้าใกล้ ADT มากที่สุด หวังว่าสักวันหนึ่งมันจะได้ถูกรวมเข้าไปใน standard library และถูกใช้อย่างแพร่หลาย
หากใช้
Messageด้วย Union จะไม่สามารถใช้การสืบทอดเมธอดได้ ตัวอย่างเช่นหากเพิ่มเมธอด
.processแบบข้างต้น ก็จะสามารถใช้เมธอด.process()ได้กับทุก variantนอกจากนี้ repr ที่ผมอธิบายหมายถึง 'repr ในฐานะที่เป็น variant ของ enum นั้น'
ตัวอย่างเช่น หากครอบการเรียก repr ด้วย fieldenum จะได้ผลลัพธ์ดังนี้
หากไม่มี
__repr__แบบกำหนดเอง ก็จะไม่สามารถแสดงให้เห็นว่าเป็น sub-variant ของ enumMessageQuitเป็น unit variant จึงใช้งานได้โดยไม่ต้องเรียกอีกทั้งในกรณีของ fieldless variant ซึ่งเป็นชนิด variant ที่ต้องใช้การเรียก ก็สามารถตรวจสอบด้วยตัวดำเนินการ
isในฐานะ singleton ได้การใช้ fieldenum จะช่วยดูแลรายละเอียดการใช้งานที่หลากหลายและพลาดได้ง่ายเหล่านี้ให้โดยอัตโนมัติ
ขออนุญาตเสนอว่า ถ้ามีโอกาสช่วยไปบรรยายที่ PyCon Korea จะเป็นอย่างไรบ้างครับ/คะ ผม/ฉันดูอย่างสนุกมากจนอยากฟังเรื่องราวและคำอธิบายเกี่ยวกับกระบวนการสร้างจากเจ้าตัวโดยตรงเลยครับ/ค่ะ!
คงจะเป็นเกียรติมากจริง ๆ ถ้าได้ไปพูดที่ PyCon นะครับ/ค่ะ ผม/ฉันก็ไม่แน่ใจเหมือนกันว่าพอแค่ผม/ฉันอยากทำแล้วจะทำได้ไหม(^^;) แต่จะลองคิดดูครับ/ค่ะ
และก็น่าจะดีถ้าใน README ภาษาอังกฤษมีการอธิบายตัวอย่างของ Option ด้วยนะครับ
เพราะ Option เข้าใจได้ง่ายและเข้าถึงได้คุ้นเคยกว่าอยู่แล้วด้วย ผมคิดว่าถ้าในลำดับการอธิบายในเอกสารอธิบาย Option ก่อนก็น่าจะดีกว่าเช่นกัน
เอกสารภาษาอังกฤษยังอยู่ระหว่างเตรียม จึงค่อนข้างสั้นไปเล็กน้อย... หากเอกสารภาษาเกาหลีสมบูรณ์พอแล้ว ผมตั้งใจจะแปลเป็นภาษาอังกฤษ หรือหากมี PR ที่เกี่ยวข้องก็ยินดีต้อนรับ!
ผมเองก็มองว่าการแนะนำ
Optionก่อนน่าจะดีกว่า จะปรับแก้ครับโอ้โห น่าสนใจมากเลยครับ!!
มีจุดที่ต้องแก้ในโค้ดตัวอย่างของเอกสารภาษาเกาหลีตามลิงก์ที่ให้มาครับ
ขอบคุณที่แจ้งให้ทราบครับ แก้ไขแล้ว!
ควรโพสต์ไปที่ Show GN แต่เผลอโพสต์เป็นหมวดทั่วไปไปซะแล้ว;;
ได้แก้ไขไว้แล้ว
ขอบคุณครับ~