Hacker News

การเปรียบเทียบตัวตรวจสอบประเภท Python: การอนุมานคอนเทนเนอร์เปล่า

เปรียบเทียบวิธีที่ตัวตรวจสอบ mypy, pyright และ Python อื่นๆ จัดการกับการอนุมานคอนเทนเนอร์เปล่า เรียนรู้การแก้ไขที่ใช้งานได้จริงสำหรับกรณีขอบการพิมพ์แบบค่อยเป็นค่อยไปในโค้ดเบสขนาดใหญ่

1 นาทีอ่าน

Mewayz Team

Editorial Team

Hacker News

เหตุใดคอนเทนเนอร์เปล่าจึงทำลายตัวตรวจสอบประเภท Python — และคุณสามารถทำอะไรได้บ้าง

ระบบการพิมพ์แบบค่อยเป็นค่อยไปของ Python พัฒนาขึ้นอย่างมากนับตั้งแต่ PEP 484 เปิดตัวคำแนะนำประเภทในปี 2558 ในปัจจุบัน นักพัฒนาหลายล้านคนอาศัยตัวตรวจสอบประเภทคงที่เพื่อตรวจจับจุดบกพร่องก่อนที่จะเริ่มใช้งานจริง แต่มีมุมที่ละเอียดอ่อนและน่าหงุดหงิดของระบบประเภทที่ยังคงสะดุดแม้แต่วิศวกรที่มีประสบการณ์: คอนเทนเนอร์เปล่ามีประเภทใด เมื่อคุณเขียน x = [] โดยไม่มีคำอธิบายประกอบ ตัวตรวจสอบประเภทของคุณจะต้องเดา — และตัวตรวจสอบต่าง ๆ จะเดาต่างกัน ความแตกต่างนี้สร้างปัญหาที่แท้จริงให้กับทีมที่ดูแลโค้ดเบสขนาดใหญ่ โดยที่การสลับหรือรวมตัวตรวจสอบประเภทสามารถตรวจพบข้อผิดพลาดที่ไม่คาดคิดนับร้อยในชั่วข้ามคืน

บทความนี้จะแจกแจงรายละเอียดว่าตัวตรวจสอบประเภท Python หลักทั้งสี่ตัว ได้แก่ mypy, pyright, pytype และ pyre จัดการกับการอนุมานคอนเทนเนอร์ว่างได้อย่างไร เหตุใดจึงไม่เห็นด้วย และกลยุทธ์เชิงปฏิบัติที่คุณสามารถนำมาใช้ในการเขียน Python ที่ปลอดภัยต่อประเภทได้ ไม่ว่าคุณจะเลือกใช้เครื่องมือใดก็ตาม

ปัญหาหลัก: ภาชนะเปล่ามีความคลุมเครือโดยธรรมชาติ

พิจารณาบรรทัด Python ที่ไม่เป็นอันตรายนี้: results = [] ผลลัพธ์เป็นรายการ [int] หรือไม่ รายการ[str]? รายการ [dict[str, Any]]? หากไม่มีบริบทเพิ่มเติม ก็ไม่มีทางรู้ได้อย่างแท้จริง รันไทม์ของ Python ไม่สนใจ รายการต่างๆ มีลักษณะต่างกัน แต่ตัวตรวจสอบประเภทคงที่จำเป็นต้องกำหนดประเภทที่เป็นรูปธรรมให้กับตัวแปรทุกตัวเพื่อทำงาน สิ่งนี้สร้างความตึงเครียดพื้นฐานระหว่างความยืดหยุ่นแบบไดนามิกของ Python และการรับประกันว่าการวิเคราะห์แบบคงที่พยายามให้ได้

ปัญหาประกอบด้วยพจนานุกรมและเซต จริงๆ แล้ว {} ที่ว่างเปล่าจะถูกแยกวิเคราะห์เป็นคำสั่ง ไม่ใช่ชุด ซึ่งเพิ่มความคลุมเครือทางวากยสัมพันธ์ที่ด้านบนของความกำกวมระดับประเภท และคอนเทนเนอร์ที่ซ้อนกัน — คิดว่า defaultdict(list) หรือ results = {k: [] for k in Keys} — ผลักดันกลไกการอนุมานให้ถึงขีดจำกัด ตัวตรวจสอบแต่ละประเภทได้พัฒนาการวิเคราะห์พฤติกรรมของตนเอง และความแตกต่างมีความสำคัญมากกว่าที่นักพัฒนาส่วนใหญ่ตระหนัก

ในระบบการผลิตที่ประมวลผลปริมาณงานจริง ไม่ว่าจะเป็น CRM ที่จัดการบันทึกลูกค้า โมดูลการออกใบแจ้งหนี้ที่สร้างบรรทัดรายการ หรือไปป์ไลน์การวิเคราะห์ที่รวบรวมเมตริก คอนเทนเนอร์ว่างจะปรากฏเป็นรูปแบบการเริ่มต้นอย่างต่อเนื่อง การทำให้ประเภทของพวกเขาผิดไม่เพียงแต่สร้างคำเตือน linder เท่านั้น มันสามารถปกปิดข้อบกพร่องของแท้ที่ส่งผ่านไปยังรันไทม์ได้

Mypy: การอนุมานแบบเลื่อนออกไปโดยปริยายใดๆ

Mypy ซึ่งเป็นเครื่องมือตรวจสอบประเภท Python ที่เก่าแก่และนำมาใช้กันอย่างแพร่หลายที่สุด ใช้แนวทางที่ค่อนข้างผ่อนปรนกับคอนเทนเนอร์เปล่า เมื่อพบ x = [] ที่ขอบเขตฟังก์ชัน ระบบจะพยายามเลื่อนการตัดสินใจประเภทและอนุมานประเภทองค์ประกอบจากการใช้งานในภายหลัง หากคุณเขียน x = [] ตามด้วย x.append(42) mypy จะอนุมาน list[int] กลยุทธ์ "เข้าร่วม" นี้ใช้ได้ผลดีอย่างน่าประหลาดใจสำหรับกรณีที่ตรงไปตรงมาซึ่งมีการเติมคอนเทนเนอร์ภายในขอบเขตเดียวกัน

💡 คุณรู้หรือไม่?

Mewayz ทดแทนเครื่องมือธุรกิจ 8+ รายการในแพลตฟอร์มเดียว

CRM · การออกใบแจ้งหนี้ · HR · โปรเจกต์ · การจอง · อีคอมเมิร์ซ · POS · การวิเคราะห์ แผนฟรีใช้ได้ตลอดไป

เริ่มฟรี →

อย่างไรก็ตาม พฤติกรรมของ mypy เปลี่ยนแปลงไปอย่างมากขึ้นอยู่กับบริบทและการตั้งค่าที่เข้มงวด ที่ขอบเขตของโมดูล (โค้ดระดับบนสุด) หรือเมื่อคอนเทนเนอร์ถูกส่งผ่านไปยังฟังก์ชันอื่นก่อนที่จะถูกเติม mypy มักจะถอยกลับไปที่ list[Any] ภายใต้แฟล็ก --strict สิ่งนี้จะทำให้เกิดข้อผิดพลาด แต่ในโหมดดีฟอลต์ แฟล็กจะผ่านไปโดยไม่แจ้งให้ทราบ ซึ่งหมายความว่าทีมที่รัน mypy โดยไม่มีโหมดเข้มงวดสามารถสะสมคอนเทนเนอร์ที่พิมพ์โดยปริยายได้หลายสิบคอนเทนเนอร์ซึ่งทำหน้าที่เป็นช่องหลบหนีออกจากระบบประเภท โดยเอาชนะจุดประสงค์ของมันได้

พฤติกรรมที่ละเอียดอ่อนอย่างหนึ่ง: เวอร์ชัน mypy ก่อนหน้า 0.990 บางครั้งจะอนุมาน list[Unknown] ภายในแล้วขยายเป็น list[Any] ในงานที่ได้รับมอบหมาย หลัง 0.990 การอนุมานถูกทำให้รัดกุม แต่การเปลี่ยนแปลงนี้ได้ทำลายฐานโค้ดในโลกแห่งความเป็นจริงจำนวนมากที่น่าประหลาดใจซึ่งอาศัยพฤติกรรมที่อนุญาตโดยที่ไม่รู้ตัว นี่เป็นธีมที่เกิดซ้ำ — การเปลี่ยนแปลงการอนุมานคอนเทนเนอร์ว่างเป็นหนึ่งในการอัปเดตตัวตรวจสอบประเภทที่ก่อกวนมากที่สุด เนื่องจากมีรูปแบบที่แพร่หลายมาก

Pyright: การอนุมานที่เข้มงวดและประเภท "ไม่ทราบ"

Pyright ซึ่งพัฒนาโดย Microsoft และขับเคลื่อน Pylance ใน VS Code มีจุดยืนทางปรัชญาที่แตกต่างโดยพื้นฐาน แทนที่จะอยู่เงียบๆ

Build Your Business OS Today

From freelancers to agencies, Mewayz powers 138,000+ businesses with 207 integrated modules. Start free, upgrade when you grow.

Create Free Account →
... ***

Frequedntly Asked Questions

คอนเทนเนอร์เปล่ามีประเภทอย่างไรบ้างใน Python และทำไมจะสร้างปัญหา?

คอนเทนเนอร์เปล่าที่ไม่มีค่าหรือข้อมูลเก็บไว้ไม่มีประเภทที่ชัดเจนในการตรวจสอบประเภท Python สำหรับตัวแปรเช่น x = [] ตัวตรวจสอบต่าง ๆ สามารถสร้างประเภทที่แตกต่างกัน เช่น List[Any] List[Never] หรืออาจไม่สร้างประเภทเลย ทำให้เกิดปัญหาในการรวมโค้ดจากหลายๆ ทีม และทำให้พร้อมการเขียนโปรแกรมไม่มั่นใจ

ปัญหานี้สำคัญต่อการพัฒนาโปรแกรมขนาดใหญ่อย่างไร?

ในโครงการขนาดใหญ่ที่มีทีมพัฒนาไม่น้อย มีโค้ดที่สร้างและดูแลโดยคนต่างๆ มาก ในกรณีที่คอนเทนเนอร์เปล่ามีประเภทที่ไม่แน่นอน ทีมหนึ่งอาจสร้าง x = []: List[Any] ส่วนทีมอื่นๆ อาจสร้าง x = []: List[Never] หรือไม่มีการประกาศประเภทเลย ทำให้เกิดข้อผิดพลาดในการรวมโค้ด และปัญหาในการตรวจสอบประเภท

มีวิธีแก้ไขปัญหานี้หรือไม่ ถ้ามีแล้ววิธีไหนบางส่ง?

มีวิธีแก้ไขหลายวิธี สามารถใช้ประเภท Union แบบง่ายๆ เช่น x: list[Any] = [] หรือใช้ประเภทเฉพาะ เช่น x: list[str] = [] หากคุณรู้ประเภทของข้อมูลที่จะเก็บ หรือใช้การประ

Frequently Asked Questions

คำถาม 1: คอนเทนเนอร์เปล่าคืออะไร และทำไมจะสร้างปัญหาให้กับการตรวจสอบประเภท?

คอนเทนเนอร์เปล่าเป็นโครงสร้างข้อมูลที่ไม่มีค่าเริ่มต้น เช่นรายการเปล่าหรือตารางเปล่าที่ไม่มีสมาชิก คำตอบสร้างปัญหาเพราะตัวตรวจสอบประเภทต้องประมาณประเภทจากบริบทโดยไม่มีข้อมูลชัดเจน ตัวตรวจสอบแต่ละตัวอาจตัดสินใจต่างกัน ทำให้เกิดผลลัพธ์ที่ไม่สอดคล้องกัน

คำถาม 2: ตัวตรวจสอบประเภทจะตั้งการประเภทคอนเทนเนอร์เปล่าหลังจากการประกาศไว้หรือไม่?

ตกคือไม่ จะ ตัวตรวจสอบประเภท Python ไม่สามารถตั้งประเภทคอนเทนเนอร์เปล่าหลังจากการประกาศมาจากการประกาศเพราะไม่มีข้อมูลเพียงพอในตอนนั้น ตัวตรวจสอบต้องรอจนมีการเพิ่มสมาชิกเข้าก่อนที่จะสามารถตั้งประเภทได้อย่างชัดเจน

คำถาม 3: มีวิธีไหนบางวิธีเพื่อลดปัญหาเหลือหางจากคอนเทนเนอร์เปล่าในการตรวจสอบประเภท?

ลองใช้ Mewayz ฟรี

แพลตฟอร์มแบบออล-อิน-วันสำหรับ CRM, การออกใบแจ้งหนี้, โครงการ, HR และอื่นๆ ไม่ต้องใช้บัตรเครดิต

เริ่มจัดการธุรกิจของคุณอย่างชาญฉลาดวันนี้

เข้าร่วมธุรกิจ 30,000+ ราย แผนฟรีตลอดไป · ไม่ต้องใช้บัตรเครดิต

พบว่าสิ่งนี้มีประโยชน์หรือไม่? แบ่งปันมัน

พร้อมนำไปปฏิบัติแล้วหรือยัง?

เข้าร่วมธุรกิจ 30,000+ รายที่ใช้ Mewayz แผนฟรีตลอดไป — ไม่ต้องใช้บัตรเครดิต

เริ่มต้นทดลองใช้ฟรี →

พร้อมที่จะลงมือทำหรือยัง?

เริ่มต้นทดลองใช้ Mewayz ฟรีวันนี้

แพลตฟอร์มธุรกิจแบบครบวงจร ไม่ต้องใช้บัตรเครดิต

เริ่มฟรี →

ทดลองใช้ฟรี 14 วัน · ไม่ต้องใช้บัตรเครดิต · ยกเลิกได้ทุกเมื่อ