คำอธิบายประกอบประเภทการส่งคืน Python เป็นโมฆะ


125

ใน python 3.x เป็นเรื่องปกติที่จะใช้คำอธิบายประกอบชนิด return ของฟังก์ชันเช่น:

def foo() -> str:
    return "bar"

คำอธิบายประกอบที่ถูกต้องสำหรับประเภท "โมฆะ" คืออะไร?

ฉันกำลังพิจารณา 3 ตัวเลือก:

  1. def foo() -> None:
    • ไม่ใช่ IMO เชิงตรรกะเพราะNoneไม่ใช่ประเภท
  2. def foo() -> type(None):
    • โดยใช้ไวยากรณ์ที่ดีที่สุดที่ฉันรู้จักเพื่อให้ได้NoneTypeมา
  3. def foo():
    • ละเว้นข้อมูลประเภทการส่งคืนที่ชัดเจน

ตัวเลือกที่ 2 ดูเหมือนจะสมเหตุสมผลที่สุดสำหรับฉัน แต่ฉันได้เห็นบางกรณีของ 1 แล้ว


12
FWIW, Python ไม่มีฟังก์ชันที่มีvoidประเภทการส่งคืน ฟังก์ชั่นใด ๆ (หรือสาขาในฟังก์ชั่น) โดยไม่ชัดเจนจะกลับreturn Noneผมถือว่า OP เข้าใจดีความคิดเห็นนี้ส่วนใหญ่เป็นประโยชน์ต่อผู้อ่านในอนาคต ...
PM 2Ring

คำถามนี้ไม่ได้รับความนิยมเท่ากับ "เหตุใดฟังก์ชันของฉันจึงส่งคืน None ใน Python" (ฉันตั้งคำถามนี้ขึ้นมา) ดังนั้นผู้อ่านส่วนใหญ่อาจทราบพฤติกรรมเริ่มต้นแล้ว คำตอบ 1 vs 2 ได้รับการแก้ไขแล้ว แต่ 3 ล่ะ? สำหรับ "ขั้นตอน" จริงๆแล้วฉันต้องการตัวเลือกที่ 3 โดยไม่มีความยุ่งเหยิงที่ไร้ประโยชน์ (หลังจากนั้นฟังก์ชันนี้จะไม่ส่งคืนอะไรเลย)
Tomasz Gandor

@TomaszGandor เห็นด้วย. เมื่อฟังก์ชันหรือเมธอดไม่มีคำสั่ง return ก็ไม่จำเป็นต้องระบุประเภทการส่งคืน
Jeyekomon

คำตอบ:


136

ตรงจากเอกสารPEP 484 - Type Hints :

เมื่อนำมาใช้ในคำใบ้ชนิดแสดงออกถือว่าเทียบเท่ากับNonetype(None)

และอย่างที่คุณเห็นตัวอย่างส่วนใหญ่ใช้Noneเป็นประเภทผลตอบแทน


23
หากต้องการชี้แจงให้เลือกตัวเลือกที่ 1 ด้านบน
Adam Nelson

6
แล้วประเภทNoReturn python.org/dev/peps/pep-0484/#the-noreturn-typeล่ะ
asmaier

13
@asmaier ตามคำถามนี้ซึ่งอ้างถึงPEP 484 - ประเภทคำแนะนำ NoReturnประเภทถูกใช้ "... เพื่อใส่คำอธิบายประกอบฟังก์ชันที่ไม่กลับมาเป็นปกติตัวอย่างเช่นฟังก์ชันที่ยกข้อยกเว้นโดยไม่มีเงื่อนไข ... "
Rodrigo Laguna

44

TLDR: เทียบเท่าสำนวนของชนิดกลับเป็นคำอธิบายประกอบvoid-> None

def foo() -> None:
    ...

นี้ตรงกับที่ฟังก์ชั่นโดยไม่ต้องreturnหรือเพียงแค่เปลือยประเมินreturnNone

def void_func():  # unannotated void function
    pass

print(void())  # None

การละเว้นประเภทการส่งคืนไม่ได้หมายความว่าไม่มีค่าส่งคืน ตามPEP 484 :

Anyสำหรับฟังก์ชั่นการตรวจสอบบันทึกย่อเริ่มต้นสำหรับการขัดแย้งและสำหรับประเภทกลับเป็น

ซึ่งหมายความว่าค่าจะถือว่าพิมพ์แบบไดนามิกและแบบคงที่สนับสนุนการดำเนินงานใดvoidนั่นคือในทางปฏิบัติตรงข้ามกับความหมายของ


คำใบ้ประเภทใน Python ไม่จำเป็นต้องใช้ประเภทจริงอย่างเคร่งครัด ยกตัวอย่างเช่นคำอธิบายประกอบอาจจะใช้สตริงชื่อประเภท: Union[str, int], Union[str, 'int'], 'Union[str, int]'และตัวแปรต่างๆที่เทียบเท่า

ในทำนองเดียวกันคำอธิบายประกอบประเภทNoneจะถือว่ามีความหมายว่า "เป็นของNoneType" สิ่งนี้สามารถใช้ได้ไม่เพียง แต่สำหรับประเภทการส่งคืน แต่คุณจะเห็นบ่อยที่สุดที่นั่น

bar : None

def foo(baz: None) -> None:
    return None

นอกจากนี้ยังใช้กับประเภททั่วไป ตัวอย่างเช่นคุณสามารถใช้NoneในGenerator[int, None, None]การบ่งชี้ถึงการกำเนิดไฟฟ้าไม่ได้ใช้หรือค่าตอบแทน


แม้ว่า PEP 484 จะแนะนำว่าNoneหมายความว่าtype(None)คุณไม่ควรใช้รูปแบบหลังอย่างโจ่งแจ้ง ข้อกำหนดประเภทเค้าไม่ได้type(...)รวมถึงรูปแบบของการใด ๆ นี่คือนิพจน์รันไทม์ในทางเทคนิคและการสนับสนุนขึ้นอยู่กับตัวตรวจสอบประเภททั้งหมด mypyโครงการพิจารณาเพื่อลบการสนับสนุนสำหรับtype(None)และนำออกจาก 484 เป็นอย่างดี

หรือบางทีเราควรอัปเดต PEP 484 เพื่อไม่ให้แนะนำว่าtype(None)ถูกต้องเป็นประเภทและNoneเป็นการสะกดที่ถูกต้องเท่านั้นหรือ ควรมีวิธีเดียวและควรมีเพียงวิธีเดียวเท่านั้นที่จะทำได้เป็นต้น

--- JukkaL 18 พ.ค. 2561


4
คำพูดขนาดใหญ่สำหรับการอธิบายว่าเหตุใดตัวเลือกที่ 3 จึงไม่ใช่ฟังก์ชันที่เป็นโมฆะเลย
никта
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.