นักพัฒนา Python ถกเถียงไวยากรณ์แบบย่อสำหรับ Keyword Arguments ตามแนวปฏิบัติที่ดีของ Dataclass

ทีมชุมชน BigGo
นักพัฒนา Python ถกเถียงไวยากรณ์แบบย่อสำหรับ Keyword Arguments ตามแนวปฏิบัติที่ดีของ Dataclass

การอภิปรายล่าสุดเกี่ยวกับแนวปฏิบัติที่ดีของ Python dataclass ได้จุดประกายการถกเถียงในชุมชนที่กว้างขึ้นเกี่ยวกับการจัดการ keyword arguments ของภาษานี้และความจำเป็นในการใช้ไวยากรณ์ที่กระชับกว่า การสนทนาเริ่มต้นด้วยคำแนะนำในการใช้ keyword-only arguments ใน dataclasses แต่ได้พัฒนาไปสู่การตรวจสอบเชิงลึกเกี่ยวกับความยาวเยิ่นของ Python เมื่อเปรียบเทียบกับภาษาโปรแกรมมิ่งอื่น ๆ

การเปรียบเทียบไวยากรณ์ Keyword-Only ของ Python Dataclass

dataclass แบบดั้งเดิม:

@dataclass
class MyDataClass:
    x: int
    y: str
    z: bool = True

dataclass แบบ keyword-only (แนะนำ):

@dataclass(kw_only=True)
class MyDataClass:
    x: int
    y: str
    z: bool = True

ความแตกต่างในการใช้งาน:

  • แบบดั้งเดิม: MyDataClass(1, 'foo', False)
  • แบบ keyword-only: MyDataClass(x=1, y='foo', z=False)

ปัญหาความยาวเยิ่น

นักพัฒนา Python รู้สึกหงุดหงิดมากขึ้นกับลักษณะที่ซ้ำซากของ keyword arguments โดยเฉพาะเมื่อชื่อตัวแปรตรงกับชื่อพารามิเตอร์ทุกประการ ข้อกำหนดปัจจุบันที่ต้องเขียน function(x=x, y=y, z=z) ทำให้โปรแกรมเมอร์หลายคนที่เคยสัมผัสกับวิธีแก้ปัญหาที่สวยงามกว่าในภาษาอื่น ๆ รู้สึกว่ามันยาวเยิ่นโดยไม่จำเป็น

ไวยากรณ์แบบย่อสำหรับ property ของ JavaScript ได้กลายเป็นจุดที่นักพัฒนา Python อิจฉาเป็นพิเศษ ใน JavaScript นักพัฒนาสามารถเขียนแค่ {x, y, z} แทนที่จะเป็น {x: x, y: y, z: z} เมื่อชื่อ property ตรงกับชื่อตัวแปร ฟีเจอร์นี้ช่วยลดการทำซ้ำของโค้ดและปรับปรุงความสามารถในการอ่านได้อย่างมาก

ความพยายามแก้ปัญหาที่ล้มเหลว

ชุมชน Python ได้พยายามแก้ไขปัญหานี้ผ่านช่องทางอย่างเป็นทางการ PEP 736 เสนอไวยากรณ์แบบย่อโดยใช้สัญลักษณ์ fn(x=, y=, z=) แต่ข้อเสนอนี้ถูกปฏิเสธในที่สุด นักพัฒนาหลายคนแสดงความโล่งใจกับการปฏิเสธนี้ โดยรู้สึกว่าไวยากรณ์ที่เสนอมานั้นแปลกและไม่ได้ให้วิธีแก้ปัญหาที่สวยงามตามที่พวกเขาหวังไว้

จากที่ดูแล้ว ความรู้สึกที่ฉันได้รับคือข้อเสนอไวยากรณ์ที่ดีและสะดวกได้ถูกปฏิเสธเพราะการถกเถียงเรื่องเล็กน้อย

สมาชิกชุมชนได้เสนอแนวทางทางเลือกหลายแบบ บางคนเสนอการใช้ไวยากรณ์แบบ OCaml ด้วยสัญลักษณ์ tilde ในขณะที่คนอื่น ๆ แนะนำแนวทาง semicolon prefix ของ Julia อย่างไรก็ตาม ทางเลือกเหล่านี้ไม่ได้รับการสนับสนุนหรือการพิจารณาอย่างเป็นทางการอย่างมีนัยสำคัญ

โซลูชันไวยากรณ์แบบย่อที่เสนอสำหรับ Python

ภาษา ไวยากรณ์ปัจจุบัน ไวยากรณ์แบบย่อ สถานะ
JavaScript {x: x, y: y, z: z} {x, y, z} ใช้งานได้
Python (PEP 736) fn(x=x, y=y, z=z) fn(x=, y=, z=) ถูกปฏิเสธ
OCaml-style fn(x=x, y=y) fn(~x, ~y) เสนอแนะ
Julia-style fn(x=x, y=y) fn(;x, y) เสนอแนะ

วิธีแก้ปัญหาชั่วคราวใน Python ปัจจุบัน: f(**{x, y, z}) - ใช้การแกะ dictionary แต่อ่านยากกว่า

วิธีแก้ปัญหาชั่วคราวและวิธีแก้ปัจจุบัน

แม้จะไม่มีไวยากรณ์แบบย่อดั้งเดิม นักพัฒนา Python ก็ได้พบวิธีแก้ปัญหาชั่วคราวที่สร้างสรรค์ วิธีหนึ่งคือการใช้ dictionary unpacking ด้วย f(**{x, y, z}) แม้ว่าไวยากรณ์นี้จะไม่ค่อยสวยงามและอาจทำให้เกิดความสับสนในการอ่าน

ชุมชนยังได้ยอมรับ TypedDict เป็นวิธีแก้ปัญหาสำหรับเอกสารที่ดีกว่าและการสนับสนุนจาก IDE เมื่อต้องจัดการกับ keyword arguments แนวทางนี้ช่วยแก้ไขจุดเจ็บปวดบางส่วนเกี่ยวกับการใช้ ** kwargs โดยเฉพาะในไลบรารีเช่น boto3 ที่เอกสารพารามิเตอร์มีคุณภาพไม่ดีในอดีต

การถกเถียงปรัชญาที่กว้างขึ้น

การอภิปรายได้เปิดเผยความตึงเครียดพื้นฐานในปรัชญาการออกแบบของ Python นักพัฒนาบางคนโต้แย้งว่าการที่ Python ชอบไวยากรณ์ที่ชัดเจนและเฉพาะกิจมากกว่า composable primitives กำลังนำภาษาไปสู่ความซับซ้อนที่ไม่จำเป็น พวกเขากังวลว่า Python กำลังเข้าใกล้สถานการณ์ที่คล้ายกับ C++ ที่ไวยากรณ์กลายเป็นเรื่องกว้างขวางมากจนนักพัฒนาเพียงไม่กี่คนเท่านั้นที่เข้าใจอย่างครอบคลุม

คนอื่น ๆ ปกป้องแนวทางปัจจุบันของ Python โดยโต้แย้งว่าไวยากรณ์ที่ชัดเจนและการครอบคลุมไลบรารีมาตรฐานที่ครบถ้วนช่วยลดความจำเป็นในการพึ่งพาภายนอกและทำให้โค้ดอ่านง่ายขึ้นในระยะยาว

บทสรุป

แม้ว่าตัวกระตุ้นโดยตรงสำหรับการอภิปรายนี้จะเป็นแนวปฏิบัติที่ดีของ dataclass แต่มันได้เปิดเผยความกังวลที่ลึกซึ้งกว่าเกี่ยวกับวิวัฒนาการและการออกแบบไวยากรณ์ของ Python ชุมชนยังคงแบ่งแยกเกี่ยวกับว่า Python ต้องการไวยากรณ์ที่กระชับกว่าสำหรับรูปแบบทั่วไปหรือไม่ หรือว่าแนวทางที่ชัดเจนในปัจจุบันให้บริการเป้าหมายของภาษาในด้านความสามารถในการอ่านและการบำรุงรักษาได้ดีกว่า ขณะที่ Python ยังคงพัฒนาต่อไป การถกเถียงเหล่านี้น่าจะมีอิทธิพลต่อการตัดสินใจออกแบบภาษาในอนาคตและทิศทางของ PEPs ที่จะมาถึง

อ้างอิง: Tip: Use keyword-only arguments in Python dataclasses