Python ค่อนข้างแปลกที่มันเก็บทุกอย่างไว้ในพจนานุกรมสำหรับขอบเขตต่างๆ ต้นฉบับ a, b, c อยู่ในขอบเขตบนสุดและอื่น ๆ ในพจนานุกรมบนสุดนั้น ฟังก์ชั่นมีพจนานุกรมของตัวเอง เมื่อคุณมาถึงprint(a)
และprint(b)
ข้อความสั่งไม่มีชื่อใดในพจนานุกรมดังนั้น Python ค้นหารายการและค้นหาในพจนานุกรมทั่วโลก
ตอนนี้เราได้รับซึ่งเป็นของหลักสูตรที่เทียบเท่ากับc+=1
c=c+1
เมื่อ Python สแกนบรรทัดนั้นจะมีข้อความว่า "aha มีตัวแปรชื่อ c ฉันจะใส่มันลงในพจนานุกรมขอบเขตท้องถิ่นของฉัน" จากนั้นเมื่อมันไปหาค่าสำหรับ c สำหรับ c ทางด้านขวามือของการมอบหมายมันจะพบตัวแปรท้องถิ่นชื่อ cซึ่งยังไม่มีค่าและยังโยนข้อผิดพลาด
คำสั่งglobal c
ดังกล่าวข้างต้นเพียงบอก parser ว่ามันใช้c
จากขอบเขตทั่วโลกและดังนั้นจึงไม่จำเป็นต้องมีใหม่
เหตุผลที่บอกว่ามีปัญหาในบรรทัดเนื่องจากเป็นอย่างมีประสิทธิภาพค้นหาชื่อก่อนที่จะพยายามสร้างรหัสและในบางกรณีไม่คิดว่ามันกำลังทำสายนั้น ฉันยืนยันว่าเป็นข้อผิดพลาดในการใช้งาน แต่โดยทั่วไปแล้วเป็นวิธีปฏิบัติที่ดีเพียงแค่เรียนรู้ที่จะไม่ใช้ข้อความของคอมไพเลอร์อย่างจริงจังเกินไป
ถ้ามันสะดวกสบายฉันอาจใช้เวลาหนึ่งวันขุดและทดลองกับปัญหาเดียวกันนี้ก่อนที่ฉันจะพบบางสิ่งที่กุยโด้เขียนเกี่ยวกับพจนานุกรมที่อธิบายทุกอย่าง
อัพเดทดูความคิดเห็น:
มันไม่สแกนโค้ดสองครั้ง แต่สแกนรหัสในสองขั้นตอนคือการอ่านและแยก
พิจารณาว่าการแยกวิเคราะห์รหัสบรรทัดนี้ทำงานอย่างไร lexer อ่านข้อความต้นฉบับและแบ่งออกเป็น lexemes "ส่วนประกอบที่เล็กที่สุด" ของไวยากรณ์ ดังนั้นเมื่อมันกระทบกับเส้น
c+=1
มันแบ่งมันออกเป็นสิ่งที่ชอบ
SYMBOL(c) OPERATOR(+=) DIGIT(1)
ตัวแยกวิเคราะห์ในที่สุดต้องการทำให้สิ่งนี้เป็นทรีแยกวิเคราะห์และดำเนินการ แต่เนื่องจากเป็นการมอบหมายก่อนที่มันจะค้นหาชื่อ c ในพจนานุกรมท้องถิ่นไม่เห็นและแทรกในพจนานุกรมการทำเครื่องหมาย มันไม่ได้กำหนดค่าเริ่มต้น ในภาษาที่รวบรวมอย่างสมบูรณ์มันจะเข้าไปในตารางสัญลักษณ์และรอการแยกวิเคราะห์ แต่เนื่องจากมันไม่มีความหรูหราในรอบที่สอง lexer จึงทำงานพิเศษเล็กน้อยเพื่อทำให้ชีวิตง่ายขึ้นในภายหลัง เท่านั้นจากนั้นจะเห็นผู้ดำเนินการเห็นว่ากฎบอกว่า "ถ้าคุณมีผู้ดำเนินการ + = ด้านซ้ายมือจะต้องได้รับการเริ่มต้น" และพูดว่า "โอ้โห!"
จุดนี่คือมันยังไม่ได้เริ่มแยกวิเคราะห์ของบรรทัดยังไม่ได้เริ่มต้นจริงๆแยกของบรรทัดเลยนี่คือสิ่งที่เกิดขึ้นในการเตรียมการกับการแยกวิเคราะห์จริงดังนั้นตัวนับบรรทัดจึงไม่ก้าวหน้าไปสู่บรรทัดถัดไป ดังนั้นเมื่อมันส่งสัญญาณข้อผิดพลาดมันก็ยังคิดว่ามันอยู่ในบรรทัดก่อนหน้า
อย่างที่ฉันบอกคุณอาจโต้แย้งว่ามันเป็นข้อผิดพลาดในการใช้งาน แต่จริงๆแล้วมันเป็นเรื่องธรรมดา คอมไพเลอร์บางคนมีความซื่อสัตย์ต่อมันมากกว่าและพูดว่า "เกิดข้อผิดพลาดหรือใกล้เคียงกับบรรทัด XXX" แต่อันนี้ไม่มี