พฤติกรรมลำไส้ใหญ่แปลก ๆ นี้กำลังทำอะไรอยู่?


104

ฉันใช้ Python 3.6.1 และฉันเจอบางอย่างที่แปลกมาก ฉันมีการพิมพ์คำผิดในพจนานุกรมง่ายๆซึ่งใช้เวลานานในการค้นหา

context = {}
context["a"]: 2
print(context)

เอาต์พุต

{}

โค้ดใช้context["a"]: 2ทำอะไร? ไม่ได้เพิ่มSyntaxErrorเวลาที่ควร IMO ตอนแรกคิดว่าเป็นการสร้างฝาน อย่างไรก็ตามการพิมพ์repr(context["a"]: 2)จะทำให้เกิดไฟล์SyntaxError. ฉันพิมพ์context["a"]: 2ในคอนโซลด้วยและคอนโซลไม่ได้พิมพ์อะไรเลย ฉันคิดว่ามันอาจจะกลับมาNoneแต่ฉันไม่แน่ใจ

ฉันยังคิดว่ามันอาจเป็นคำสั่ง if บรรทัดเดียว แต่นั่นก็ไม่ควรเป็นไวยากรณ์ที่ถูกต้องเช่นกัน

นอกจากนี้context["a"]ควรเพิ่มไฟล์KeyError.

ฉันงง เกิดอะไรขึ้น?


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

1
สิ่งนี้ตอบคำถามของคุณหรือไม่? คำอธิบายประกอบตัวแปรใน Python 3.6 คืออะไร?
Georgy

คำตอบ:


98

คุณได้เขียนถูกต้อง syntactically ตั้งใจคำอธิบายประกอบตัวแปร คุณลักษณะดังกล่าวได้รับการแนะนำใน Python 3.6 (ดูPEP 526 )

แม้ว่าคำอธิบายประกอบตัวแปรจะถูกแยกวิเคราะห์เป็นส่วนหนึ่งของการกำหนดคำอธิบายประกอบคำสั่งมอบหมายเป็นทางเลือก :

annotated_assignment_stmt ::=  augtarget ":" expression ["=" expression]

ดังนั้นใน context["a"]: 2

  • context["a"] คือเป้าหมายคำอธิบายประกอบ
  • 2 คือคำอธิบายประกอบเอง
  • context["a"] ถูกปล่อยทิ้งไว้โดยไม่ได้เริ่มต้น

PEP ระบุว่า"เป้าหมายของคำอธิบายประกอบสามารถเป็นเป้าหมายการกำหนดเดียวที่ถูกต้องอย่างน้อยก็มีการใช้ไวยากรณ์ (ขึ้นอยู่กับตัวตรวจสอบประเภทว่าจะทำอย่างไรกับสิ่งนี้)"ซึ่งหมายความว่าไม่จำเป็นต้องมีคีย์ มีคำอธิบายประกอบ (จึงไม่KeyError) นี่คือตัวอย่างจาก PEP ดั้งเดิม:

d = {}
d['a']: int = 0  # Annotates d['a'] with int.
d['b']: int      # Annotates d['b'] with int.

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

ที่คุณสามารถดูในเวลานี้ประเภทคำแนะนำเป็นอย่างอนุญาตและมีประโยชน์ไม่ค่อยได้จนกว่าคุณจะมีการตรวจสอบประเภทคงที่เช่นmypy


12
สิ่งนี้ไม่ควรต้องมี=ผู้ดำเนินการมอบหมายหรือไม่? ไม่มีคีย์ แค่นี้ก็รู้สึกผิดกับฉันแล้ว
justengel

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

1
@chepner ดูเหมือนว่านี่จะไม่มีผลข้างเคียง imho นี่คือสิ่งที่ PEP ที่เกี่ยวข้องได้รับการออกแบบมาให้ทำ

6
มันแปลกที่มันจะช่วยให้คุณใส่คำอธิบายประกอบเป้าหมายที่ยังไม่ได้กำหนดได้ ถ้าบรรทัดแรกของฉันคือx: strและตามด้วยทันทีtype(x)ล่ามจะยก a NameError. IMO ไวยากรณ์ควรบังคับใช้กับออบเจ็กต์ที่กำหนดไว้ล่วงหน้าหรือกำหนดไว้ตรงจุด นี่เป็นเพียงการแนะนำความสับสน
r.ook

2
@Idlehands สิ่งนี้เอาชนะวัตถุประสงค์แม้ว่า การมีมาx = 'i am a string'ก่อนx: strทำให้ประเภทหลังซ้ำซ้อน .. แบบนี้ไม่ควรเพิ่มเลย เป็นความคิดเห็นที่ดี; ฉันไม่เคยแสดงว่ามันใช้ไม่ทางใดก็ทางหนึ่ง
Ma0
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.