คำตอบอื่น ๆ ทำได้ดีในการอธิบายการพิมพ์เป็ดและคำตอบง่ายๆโดย tzot :
Python ไม่มีตัวแปรเช่นภาษาอื่น ๆ ที่ตัวแปรมีชนิดและค่า มันมีชื่อที่ชี้ไปยังวัตถุซึ่งทราบประเภทของวัตถุเหล่านั้น
อย่างไรก็ตามสิ่งหนึ่งที่น่าสนใจมีการเปลี่ยนแปลงตั้งแต่ปี 2010 (เมื่อคำถามถูกถามครั้งแรก) คือการดำเนินการของPEP 3107 (ดำเนินการใน Python 3) ตอนนี้คุณสามารถระบุประเภทของพารามิเตอร์และชนิดของชนิดส่งคืนของฟังก์ชันดังนี้:
def pick(l: list, index: int) -> int:
return l[index]
เราจะเห็นว่าpick
ใช้พารามิเตอร์ 2 รายการl
index
และเป็นจำนวนเต็ม มันควรจะกลับจำนวนเต็ม
ดังนั้นที่นี่มันก็ส่อให้เห็นว่าl
เป็นรายการจำนวนเต็มที่เราสามารถมองเห็นได้โดยไม่ต้องใช้ความพยายามมากนัก แต่สำหรับฟังก์ชั่นที่ซับซ้อนกว่านั้นมันอาจทำให้สับสนเล็กน้อย นอกจากนี้เรายังต้องการให้ค่าเริ่มต้นเท่ากับindex
0 เพื่อแก้ปัญหานี้คุณอาจเลือกเขียนpick
ดังนี้:
def pick(l: "list of ints", index: int = 0) -> int:
return l[index]
โปรดทราบว่าตอนนี้เราใส่สตริงเป็นประเภทของ l
ซึ่งได้รับอนุญาตทาง syntactically แต่มันไม่ดีสำหรับการแยกวิเคราะห์ทางโปรแกรม (ซึ่งเราจะกลับมาในภายหลัง)
เป็นเรื่องสำคัญที่จะต้องทราบว่า Python จะไม่ยกระดับTypeError
หากคุณส่งทุ่นเข้ามาindex
เหตุผลนี้เป็นหนึ่งในประเด็นหลักในปรัชญาการออกแบบของ Python: "เราทุกคนยินยอมผู้ใหญ่ที่นี่"ซึ่งหมายความว่าคุณคาดหวังว่าจะ ระวังสิ่งที่คุณสามารถส่งผ่านไปยังฟังก์ชั่นและสิ่งที่คุณทำไม่ได้ หากคุณต้องการเขียนโค้ดที่พ่น TypeErrors จริงๆคุณสามารถใช้isinstance
ฟังก์ชั่นเพื่อตรวจสอบว่าอาร์กิวเมนต์ที่ส่งผ่านนั้นเป็นประเภทที่เหมาะสมหรือคลาสย่อยของมันดังนี้:
def pick(l: list, index: int = 0) -> int:
if not isinstance(l, list):
raise TypeError
return l[index]
ข้อมูลเพิ่มเติมเกี่ยวกับสาเหตุที่คุณไม่ควรทำสิ่งนี้และสิ่งที่คุณควรทำแทนที่จะพูดถึงในหัวข้อถัดไปและในความคิดเห็น
PEP 3107ไม่เพียง แต่การปรับปรุงการอ่านรหัส แต่ยังมีกรณีการใช้งานที่เหมาะสมหลายอย่างที่คุณสามารถอ่านข้อมูลเกี่ยวกับที่นี่
คำอธิบายประกอบแบบได้รับความสนใจมากขึ้นใน Python 3.5 ด้วยการเปิดตัวPEP 484ซึ่งแนะนำโมดูลมาตรฐานสำหรับคำใบ้ประเภท
คำใบ้ประเภทเหล่านี้มาจากตัวตรวจสอบชนิดmypy ( GitHub ) ซึ่งตอนนี้เป็นไปตามPEP 484
ด้วยโมดูลการพิมพ์ที่มาพร้อมคอลเลกชันคำแนะนำประเภทที่ครอบคลุมรวมถึง:
List
, Tuple
, Set
, Map
- สำหรับlist
, tuple
, set
และmap
ตามลำดับ
Iterable
- มีประโยชน์สำหรับเครื่องกำเนิดไฟฟ้า
Any
- เมื่อมันสามารถเป็นอะไรก็ได้
Union
- Any
เมื่อมันจะเป็นอะไรที่อยู่ในชุดที่ระบุประเภทเมื่อเทียบกับ
Optional
- เมื่อมันอาจจะไม่มี Union[T, None]
ชวเลข
TypeVar
- ใช้กับยาชื่อสามัญ
Callable
- ใช้สำหรับฟังก์ชั่นเป็นหลัก แต่สามารถใช้สำหรับ callables อื่น
นี่คือคำแนะนำประเภทที่พบบ่อยที่สุด รายชื่อที่สมบูรณ์สามารถพบได้ในเอกสารสำหรับโมดูลการพิมพ์
นี่คือตัวอย่างเก่าโดยใช้วิธีการเพิ่มความคิดเห็นที่แนะนำในโมดูลการพิมพ์:
from typing import List
def pick(l: List[int], index: int) -> int:
return l[index]
คุณลักษณะที่มีประสิทธิภาพอย่างหนึ่งคือคุณสมบัติCallable
ที่ช่วยให้คุณพิมพ์วิธีการใส่คำอธิบายประกอบที่รับฟังก์ชั่นเป็นอาร์กิวเมนต์ ตัวอย่างเช่น:
from typing import Callable, Any, Iterable
def imap(f: Callable[[Any], Any], l: Iterable[Any]) -> List[Any]:
"""An immediate version of map, don't pass it any infinite iterables!"""
return list(map(f, l))
ตัวอย่างด้านบนอาจมีความแม่นยำมากขึ้นด้วยการใช้งานTypeVar
แทนAny
แต่นี่เป็นแบบฝึกหัดสำหรับผู้อ่านเนื่องจากฉันเชื่อว่าฉันได้ตอบคำถามด้วยข้อมูลมากเกินไปเกี่ยวกับคุณสมบัติใหม่ที่ยอดเยี่ยมที่เปิดใช้งานโดยการบอกกล่าวแบบ
ก่อนหน้านี้เมื่อมีรหัส Python ที่มีเอกสารหนึ่งตัวอย่างเช่นSphinxฟังก์ชันการทำงานบางอย่างข้างต้นสามารถรับได้โดยการเขียนเอกสารที่จัดรูปแบบดังนี้
def pick(l, index):
"""
:param l: list of integers
:type l: list
:param index: index at which to pick an integer from *l*
:type index: int
:returns: integer at *index* in *l*
:rtype: int
"""
return l[index]
ดังที่คุณเห็นการดำเนินการนี้จะใช้จำนวนบรรทัดเพิ่มขึ้น (จำนวนที่แน่นอนขึ้นอยู่กับความชัดเจนที่คุณต้องการและวิธีการจัดรูปแบบเอกสารของคุณ) แต่ตอนนี้ควรมีความชัดเจนกับคุณว่าPEP 3107เป็นตัวเลือกที่ดีกว่าในหลาย ๆ วิธี โดยเฉพาะอย่างยิ่งเมื่อใช้ร่วมกับPEP 484ซึ่งเป็นโมดูลมาตรฐานที่กำหนดไวยากรณ์สำหรับคำแนะนำ / คำอธิบายประกอบประเภทเหล่านี้ที่สามารถใช้งานในลักษณะที่ไม่โปร่งใสและแม่นยำ แต่มีความยืดหยุ่นทำให้ การรวมกันที่มีประสิทธิภาพ
ในความเห็นส่วนตัวของฉันนี่เป็นหนึ่งในคุณสมบัติที่ยอดเยี่ยมที่สุดใน Python ฉันไม่สามารถรอให้ผู้คนเริ่มควบคุมพลังของมันได้ ขออภัยสำหรับคำตอบที่ยาว แต่นี่คือสิ่งที่เกิดขึ้นเมื่อฉันตื่นเต้น
ตัวอย่างของรหัสหลามซึ่งหนักใช้ประเภทเค้าสามารถพบได้ที่นี่