หากตีความ Python ไฟล์. pyc คืออะไร


1084

ฉันได้รับการเข้าใจว่า Python เป็นภาษาที่ถูกตีความ ...
อย่างไรก็ตามเมื่อฉันดูซอร์สโค้ดPythonของฉันฉันเห็น.pycไฟล์ซึ่ง Windows ระบุว่าเป็น "รวบรวมไฟล์ไพ ธ อน"

สิ่งเหล่านี้มาจากไหน


3
ดูstackoverflow.com/questions/11433579/…เพื่อเหตุผล ในหนึ่งคำ: ความเร็ว
user7610



หมายความว่าแม้แต่ไพ ธ อนก็มี 'เขียนครั้งเดียวทำงานได้ทุกที่' เช่นเดียวกับ Java
Mrak Vladar

2
@MrakVladar แม้แต่ Java ก็คือ "เขียนครั้งเดียวให้ทำงานทุกที่ [ที่คุณมี JVM]" Python ไม่แตกต่างกัน มันคือ "ทำงานได้ทุกที่ที่คุณมีเครื่องเสมือน Python" ความแตกต่างใหญ่คือว่าส่วนใหญ่การใช้งานหลามรวมคอมไพเลอร์และล่ามเป็นหนึ่งในปฏิบัติการมากกว่าแยกพวกเขาชอบและjava javac
chepner

คำตอบ:


660

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

เอกสารของ Python อธิบายคำจำกัดความเช่นนี้:

Python เป็นภาษาที่ถูกตีความเมื่อเทียบกับภาษาที่รวบรวมแม้ว่าความแตกต่างสามารถเลือนลางเนื่องจากการมีอยู่ของคอมไพเลอร์ bytecode ซึ่งหมายความว่าไฟล์ต้นฉบับสามารถรันได้โดยตรงโดยไม่ต้องสร้างไฟล์ที่รันได้อย่างชัดเจน


10
น่าสนใจขอบคุณ Python ถือว่าเป็นภาษาที่แปลอย่างหมดจดหรือไม่
froadie

194
@froadie: ภาษาไม่ได้ "ตีความ" หรือ "เรียบเรียง" เช่นนี้ การใช้งานเฉพาะสามารถเป็นล่ามหรือคอมไพเลอร์ (หรือไฮบริดหรือคอมไพเลอร์ JIT)
Joachim Sauer

30
หนึ่งการทดสอบของ 'รวบรวม': มันรวบรวมคำแนะนำเครื่องจริงหรือไม่? Python bytecode ไม่ใช่คำแนะนำของเครื่องและไม่มีคำแนะนำของ Java 'JVM' ดังนั้นภาษาเหล่านี้จึงไม่ได้รวบรวมโดยนิยามดังกล่าว แต่ทั้งสองโค้ด 'คอมไพล์' ถึงอินเทอร์เฟซ 'เครื่องนามธรรม' และทั้งคู่ไกลกว่าเร็วกว่าการรันโปรแกรมโดยการตีความซอร์สโค้ดโดยตรงมากขึ้นหรือน้อยลง (ซึ่งเป็นพื้นฐานของโรงเรียนเก่า)
greggo

20
จะแปลว่า 'แปล' หมายถึง 'แปล' Python จะถูกคอมไพล์ไปยัง bytecode AFAIK มีเพียง Bash เท่านั้นที่ถูก ตีความจริงๆ ภาษา "ตีความ" ที่ได้รับความนิยมอื่น ๆ ทั้งหมดได้รับการรวบรวมเป็น bytecode
bfontaine

13
ที่จริงแล้วพวกเขาคือคำแนะนำเครื่องไม่ใช่เพียงคำแนะนำเครื่องดั้งเดิมสำหรับ CPU จริงของโฮสต์ ดังนั้นทำไมเราจึงเรียกมันว่า VM? เหมือนภาษาเอสเปรันโตสำหรับภาษาแอสเซมบลีจริงๆ ทุกวันนี้เรายังมีรหัสดั้งเดิมสำหรับตัวละคร (แต่ยังคงเลียนแบบ) ความพยายามของซีพียู (Mojang เพื่อดึงดูด kiddies ที่สนใจ) Rexx เคยตีความ (หรืออาจ) อย่างแท้จริงและตีความ BAT และ CMD (และ DCL)
mckenzm

994

ฉันได้รับการเข้าใจว่า Python เป็นภาษาที่ตีความ ...

meme ที่ได้รับความนิยมนี้ไม่ถูกต้องหรือค่อนข้างถูกสร้างขึ้นจากความเข้าใจผิดของระดับภาษา (ธรรมชาติ): ความผิดพลาดที่คล้ายกันคือการพูดว่า "พระคัมภีร์เป็นหนังสือปกแข็ง" ฉันขออธิบายว่าอุปมา ...

"พระคัมภีร์" คือ "หนังสือ" ในแง่ของการเป็นชั้นหนังสือ (จริงวัตถุทางกายภาพระบุว่า) หนังสือ; หนังสือที่ระบุว่า "สำเนาของพระคัมภีร์" ควรจะมีอะไรบางอย่างพื้นฐานเหมือนกัน (เนื้อหาแม้ว่าจะเป็นภาษาต่าง ๆ ด้วยการแปลที่ยอมรับได้ระดับเชิงอรรถและคำอธิบายประกอบอื่น ๆ ) - อย่างไรก็ตามหนังสือเหล่านั้น ได้รับอนุญาตอย่างสมบูรณ์แบบที่จะแตกต่างกันในแง่มุมมากมายที่ไม่ถือว่าเป็นพื้นฐาน - ชนิดของการผูก, สีของการผูก, ตัวอักษร (s) ที่ใช้ในการพิมพ์, ภาพประกอบถ้ามี, ระยะขอบเขียนได้กว้างหรือไม่, , และอื่น ๆ และอื่น ๆ.

มีความเป็นไปได้ค่อนข้างมากที่การพิมพ์คัมภีร์ไบเบิลโดยทั่วไปจะมีผลผูกพันปกแข็ง - หลังจากนั้นเป็นหนังสือที่มีความหมายโดยทั่วไปว่าจะต้องอ่านซ้ำแล้วซ้ำอีกคั่นหนังสือไว้หลายแห่งด้วยการมองหาพอยน์เตอร์ ฯลฯ ฯลฯ และการเชื่อมโยงปกแข็งที่ดีสามารถทำสำเนาที่กำหนดได้นานขึ้นภายใต้การใช้งานดังกล่าว อย่างไรก็ตามสิ่งเหล่านี้เป็นประเด็นทางโลก (ทางปฏิบัติ) ที่ไม่สามารถใช้เพื่อตรวจสอบว่าหนังสือวัตถุจริงที่ให้มาเป็นสำเนาของคัมภีร์ไบเบิลหรือไม่: สิ่งพิมพ์ปกอ่อนเป็นไปได้อย่างสมบูรณ์!

ในทำนองเดียวกัน Python คือ "ภาษา" ในแง่ของการกำหนดระดับของการใช้ภาษาซึ่งทุกคนจะต้องคล้ายกันในบางประการพื้นฐาน (ไวยากรณ์ความหมายส่วนใหญ่ยกเว้นส่วนของผู้ที่พวกเขาได้รับอนุญาตอย่างชัดเจนแตกต่างกัน) แต่ได้รับอนุญาตอย่างเต็มที่ จะแตกต่างกันในรายละเอียด "การใช้งาน" ทุกครั้ง - รวมถึงวิธีจัดการกับแฟ้มต้นฉบับที่ได้รับไม่ว่าจะเป็นการรวบรวมแหล่งที่มาในรูปแบบระดับล่าง (และถ้าเป็นเช่นนั้นแบบฟอร์มใด - และบันทึกว่า แบบฟอร์มที่คอมไพล์ไปยังดิสก์หรือที่อื่น ๆ ) วิธีที่จะดำเนินการกับแบบฟอร์มดังกล่าวและอื่น ๆ

การใช้งานแบบดั้งเดิม CPython มักเรียกว่า "Python" เพียงช่วงสั้น ๆ - แต่เป็นเพียงหนึ่งในการนำไปใช้งานคุณภาพการผลิตหลายอย่างเคียงข้างกับ IronPython ของ Microsoft (ซึ่งรวบรวมรหัส CLR เช่น ".NET"), Jython (ซึ่งคอมไพล์กับรหัส JVM), PyPy (ซึ่งเขียนด้วยภาษา Python เองและสามารถรวบรวมรูปแบบ "แบ็คเอนด์" ที่หลากหลายรวมถึงภาษาของเครื่องที่เพิ่งสร้างขึ้น) พวกเขาคือ Python ทั้งหมด (== "การใช้งานภาษา Python") เช่นเดียวกับวัตถุหนังสือที่แตกต่างกันอย่างพิถีพิถันอาจเป็น Bibles (== "สำเนาของพระคัมภีร์")

หากคุณสนใจ CPython โดยเฉพาะมันรวบรวมไฟล์ต้นฉบับไว้ในแบบฟอร์มระดับล่างเฉพาะ Python (รู้จักกันในชื่อ "bytecode") จะทำเช่นนั้นโดยอัตโนมัติเมื่อจำเป็น (เมื่อไม่มีไฟล์ bytecode ที่สอดคล้องกับไฟล์ต้นฉบับหรือ ไฟล์ bytecode นั้นเก่ากว่าแหล่งที่มาหรือรวบรวมโดย Python เวอร์ชั่นอื่นซึ่งมักจะบันทึกไฟล์ bytecode ลงในดิสก์ (เพื่อหลีกเลี่ยงการคอมไพล์ใหม่ในอนาคต) โดยทั่วไปแล้ว OTOH IronPython จะรวบรวมรหัส CLR (บันทึกลงในดิสก์หรือไม่ขึ้นอยู่กับ) และรหัส Jython กับ JVM (บันทึกลงในดิสก์หรือไม่ - มันจะใช้.classส่วนขยายหากบันทึกไว้)

แบบฟอร์มระดับล่างเหล่านี้จะถูกดำเนินการโดย "เครื่องเสมือน" ที่เหมาะสมหรือที่เรียกว่า "ล่าม" - CPython VM, รันไทม์. Net, Java VM (aka JVM) ตามความเหมาะสม

ดังนั้นในแง่นี้ (การใช้งานทั่วไปทำอะไร) Python เป็น "ตีความภาษา" ถ้าหาก C # และ Java เป็น: ทั้งหมดของพวกเขามีกลยุทธ์การดำเนินงานโดยทั่วไปของการผลิต bytecode ก่อนจากนั้นดำเนินการผ่าน VM / ล่าม .

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


2
คำตอบที่สวยงาม การแก้ไขเพียงย่อหน้าเล็ก ๆ ในย่อหน้าสุดท้าย: Pythonถูกออกแบบมาเพื่อคอมไพล์โดยเร็วที่สุด (ฯลฯ ) เวลานี้มันเป็นภาษาจริง ๆ ด้วยการขาดระบบสแตติกและเนื้อหา เมื่อผู้คนพูดถึงภาษา "ตีความ" พวกเขามักจะหมายถึงภาษา "แบบไดนามิก"
Elazar

1
@Elazar ที่จริงแล้วการใช้งานอื่น ๆ ของ Python เช่น PyPy ซึ่งไม่ต้องเร่งรีบในการรวบรวมจัดการเพื่อทำการวิเคราะห์อย่างละเอียดมากขึ้นตามที่ต้องการโดยขาดการพิมพ์แบบสแตติกและสร้างการรวบรวมแบบทันเวลากับรหัสเครื่อง โปรแกรมที่รันนานหลายครั้ง)
Alex Martelli

Cython อยู่ตรงไหนของที่นี่? คุณจะพิจารณาว่าเป็นภาษาที่แตกต่างหรือเป็นการใช้งานของ Python นอกจากนี้ meme ของ "ตีความ" vs ที่รวบรวมอาจเป็นเพียงความสับสนของคำศัพท์เพราะ VM ของ Python มักถูกเรียกว่า "ล่าม" ของมันหรือไม่? มันจะถูกต้องเช่นเดียวกับการเรียก JVM หรือล่ามรันไทม์. NET พวกเขาทั้งสองส่วนใหญ่ตีความ bytecode เป็นรหัสเครื่อง JIT (มีข้อยกเว้นการเพิ่มประสิทธิภาพการแคชบางส่วน)
Davos

181

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

ทุกภาษาสามารถดำเนินการโดยล่ามหรือคอมไพเลอร์ ภาษาส่วนใหญ่มีการใช้งานอย่างน้อยหนึ่งประเภท (ตัวอย่างเช่นมีล่ามสำหรับ C และ C ++ และมีคอมไพเลอร์สำหรับ JavaScript, PHP, Perl, Python และ Ruby) นอกจากนี้การใช้ภาษาที่ทันสมัยส่วนใหญ่รวมทั้งล่ามและคอมไพเลอร์ (หรือแม้แต่คอมไพเลอร์หลายตัว)

ภาษาเป็นเพียงชุดของกฎทางคณิตศาสตร์ที่เป็นนามธรรม ล่ามเป็นหนึ่งในกลยุทธ์การใช้งานที่เป็นรูปธรรมสำหรับภาษา ทั้งสองอาศัยอยู่ในระดับนามธรรมที่แตกต่างอย่างสิ้นเชิง หากภาษาอังกฤษเป็นภาษาที่พิมพ์คำว่า "ตีความภาษา" จะเป็นข้อผิดพลาดประเภท คำสั่ง "Python เป็นภาษาที่ถูกตีความ" ไม่เพียง แต่เป็นเท็จ (เพราะความเท็จจะแปลว่าคำสั่งนั้นมีเหตุผลแม้ว่ามันจะผิด) มันก็ไม่สมเหตุสมผลเพราะภาษานั้นไม่สามารถนิยามได้ว่าเป็น "ตีความ".

โดยเฉพาะถ้าคุณดูการใช้งาน Python ที่มีอยู่ในปัจจุบันนี่เป็นกลยุทธ์การใช้งานที่ใช้:

  • IronPython: คอมไพล์ไปยังทรี DLR ซึ่ง DLR จะคอมไพล์กับ CIL bytecode สิ่งที่เกิดขึ้นกับ CIL bytecode นั้นขึ้นอยู่กับ CLI VES ที่คุณกำลังใช้งานอยู่ แต่ Microsoft .NET, GNU Portable.NET และ Novell Mono ในที่สุดจะรวบรวมมันเป็นรหัสของเครื่อง
  • Jython: ตีความซอร์สโค้ดของ Python จนกว่าจะระบุพา ธ ของรหัสร้อนซึ่งจะคอมไพล์เป็น JVML bytecode เกิดอะไรขึ้นกับ JVML bytecode ขึ้นอยู่กับ JVM ที่คุณกำลังใช้งาน Maxine จะรวบรวมโดยตรงกับการยกเลิกการเพิ่มประสิทธิภาพรหัสพื้นเมืองจนกว่าจะระบุเส้นทางรหัสร้อนซึ่งจากนั้นมันจะคอมไพล์ใหม่เพื่อรหัสพื้นเมืองที่ดีที่สุด HotSpot จะตีความ JVML bytecode ก่อนจากนั้นจึงรวบรวมเส้นทางรหัสร้อนเพื่อรหัสเครื่องที่ปรับให้เหมาะสม
  • PyPy: คอมไพล์ไปยัง PyPy bytecode ซึ่งจะได้รับการตีความโดย PyPy VM จนกว่าจะระบุพา ธ ของรหัสร้อนซึ่งจะรวบรวมเป็นรหัสเนทีฟ JVML bytecode หรือ CIL bytecode ขึ้นอยู่กับแพลตฟอร์มที่คุณใช้งาน
  • CPython: คอมไพล์ให้กับ CPython bytecode ซึ่งแปลแล้ว
  • Stackless Python: คอมไพล์ให้กับ CPython bytecode ซึ่งมันจะทำการตีความ
  • Unladen Swallow: คอมไพล์ให้กับ CPython bytecode ซึ่งจะทำการแปลจนกว่ามันจะระบุพา ธ ของรหัสร้อนซึ่งมันจะคอมไพล์ให้กับ LLVM IR ซึ่งคอมไพเลอร์ LLVM นั้นจะคอมไพล์ไปยังรหัสเครื่องท้องถิ่น
  • Cython: รวบรวมรหัส Python เป็นรหัส C แบบพกพาซึ่งจะถูกคอมไพล์ด้วยคอมไพเลอร์ C มาตรฐาน
  • Nuitka: รวบรวมรหัส Python ให้กับรหัส C ++ ที่ขึ้นกับเครื่องซึ่งจะถูกคอมไพล์ด้วยคอมไพเลอร์ C มาตรฐาน

คุณอาจสังเกตเห็นว่าทุกการใช้งานในรายการนั้น (รวมถึงคนอื่น ๆ ที่ฉันไม่ได้พูดถึงเช่นตัวเล็ก, Shedskin หรือ Psyco) มีคอมไพเลอร์ ในความเป็นจริงเท่าที่ฉันรู้ในปัจจุบันไม่มีการนำ Python มาใช้ซึ่งตีความอย่างหมดจดไม่มีการวางแผนการใช้งานดังกล่าวและไม่เคยมีการนำไปปฏิบัติ

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

โดยเฉพาะอย่างยิ่ง.pycไฟล์ที่คุณเห็นจะถูกเก็บไว้ในไฟล์ bytecode ที่สร้างโดย CPython, Stackless Python หรือ Unladen Swallow


5
พื้นฐานโรงเรียนเก่าเช่น MSBASIC ไม่มีรูปแบบกลาง โปรแกรมถูกตีความโดยตรงจากรูปแบบของแหล่งที่มา (หรือใกล้แหล่งที่มารูปแบบที่คำหลักถูกแสดงโดย 1 โทเค็นโทเค็นและบรรทัดที่ # 2 ไบต์ int 2 ไบต์ แต่ส่วนที่เหลือเป็นเพียง ASCII) ดังนั้นในความเป็นจริง 'goto' จะใช้เวลาต่างกันขึ้นอยู่กับจำนวนบรรทัดของแหล่งที่มาที่ต้องค้นหาผ่านการค้นหาปลายทางที่ตรงกัน นิพจน์เช่น * b-2 * cos (x) ถูกวิเคราะห์คำใหม่อย่างมีประสิทธิภาพทุกครั้งที่ถูกประมวลผล
greggo

4
@greggo: และถ้าคุณต้องการที่จะไปโรงเรียนเก่ามากขึ้นรุ่นเดิมของ BASIC เป็นคอมไพเลอร์รหัสพื้นเมือง สิ่งนี้ควรพิสูจน์ว่าแนวคิดของภาษา "เรียบเรียง" หรือ "ตีความ" ที่ไร้สาระคืออะไร
Jörg W Mittag

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

Cythonถูกกล่าวถึงใน SciPy 2009 แต่ฉันสามารถให้อภัยคุณที่ไม่รู้เกี่ยวกับเรื่องนี้ในปี 2010 (ที่นี่ฉันอยู่ในปี 2560 เพียงแค่ตอนนี้เรียนรู้เกี่ยวกับมัน) เรายังควรหาตัวอย่าง JavaScript ... Jython ไม่สมเหตุสมผลสำหรับฉัน (Java ไม่ได้ตายไปแล้วภายในปี 2009 ใช่มั้ยอืมอาจจะไม่ ... การเพิ่ม C ++ ก็ไม่ดีเท่านี้)
personal_cloud

1
@personal_cloud: ฉันไม่ได้ติดตามความคิดเห็นของคุณ ใช่แน่นอนฉันรู้เกี่ยวกับ Cython แต่สิ่งที่เกี่ยวข้องกับอะไร? มันไม่ได้ใช้งาน Python เป็นภาษาที่แตกต่างอย่างสิ้นเชิง นอกจากนี้ยังไม่ยากที่จะหาตัวอย่าง JavaScript อันที่จริงการใช้งาน JavaScript หลักที่มีอยู่ในปัจจุบันทั้งหมดมีคอมไพเลอร์ สุดท้าย Jython เป็นการใช้งานของ Python เหมือนกับการนำไปใช้ของ Python และมันเป็นการใช้งานของภาษาบนแพลตฟอร์ม Java เช่นเดียวกับการใช้งานภาษาอื่น ๆ บนแพลตฟอร์ม Java
Jörg W Mittag

61

สิ่งเหล่านี้ถูกสร้างขึ้นโดย Python interpreter เมื่อมี.pyการนำเข้าไฟล์และประกอบด้วย "คอมไพล์ bytecode" ของโมดูล / โปรแกรมที่นำเข้าความคิดที่ว่า "การแปล" จากซอร์สโค้ดไปยัง bytecode (ซึ่งจะต้องทำเพียงครั้งเดียวเท่านั้น) สามารถข้ามกับimports ที่ตามมาถ้า.pycใหม่กว่า.pyไฟล์ที่เกี่ยวข้องจึงเร่งการเริ่มต้นเพียงเล็กน้อย แต่มันก็ยังตีความ


10
จริง ยกเว้นไลบรารี่ Python หลักหลายตัวที่เขียนด้วยภาษาซีดังนั้นส่วนของการแปลแบบไพ ธ อนรันส่วนที่รันในซีคุณสามารถทำแบบเดียวกันกับบิตของโค้ดประสิทธิภาพอ่อนไหว
bwawok

44

เพื่อเพิ่มความเร็วในการโหลดโมดูล Python แคชเนื้อหาที่รวบรวมของโมดูลใน. pyc

CPython รวบรวมซอร์สโค้ดของมันเป็น "รหัสไบต์" และด้วยเหตุผลด้านประสิทธิภาพมันเก็บรหัสไบต์นี้ไว้ในระบบไฟล์เมื่อใดก็ตามที่ไฟล์ต้นฉบับมีการเปลี่ยนแปลง สิ่งนี้ทำให้การโหลดโมดูล Python เร็วขึ้นมากเนื่องจากขั้นตอนการคอมไพล์สามารถข้ามได้ เมื่อไฟล์ต้นฉบับของคุณคือ foo.py, CPython จะแคชโค้ดไบต์ในไฟล์ foo.pyc ถัดจากซอร์ส

ใน python3 เครื่องจักรนำเข้าของ Python จะถูกขยายเพื่อเขียนและค้นหาไฟล์แคชรหัสไบต์ในไดเรกทอรีเดียวภายในทุก ๆ แพ็คเกจของ Python ไดเรกทอรีนี้จะถูกเรียกว่า __pycache__

นี่คือโฟลว์แผนภูมิที่อธิบายวิธีโหลดโมดูล:

ป้อนคำอธิบายรูปภาพที่นี่

สำหรับข้อมูลเพิ่มเติม:

ref: PEP3147
อ้างอิง: ไฟล์ Python“ รวบรวม”


38

นี่คือสำหรับผู้เริ่มต้น

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

การเรียกใช้สคริปต์ไม่ถือเป็นการอิมพอร์ตและจะไม่มีการสร้าง. pyc

ตัวอย่างเช่นถ้าคุณมีไฟล์สคริปต์abc.pyการนำเข้าที่โมดูลอื่นxyz.pyเมื่อคุณเรียกabc.py , xyz.pycจะถูกสร้างขึ้นตั้งแต่ xyz จะถูกนำเข้า แต่ไม่มีไฟล์ abc.pyc จะได้รับการสร้างขึ้นตั้งแต่ abc py ไม่ได้ถูกนำเข้า

หากคุณต้องการสร้างไฟล์. pyc สำหรับโมดูลที่ไม่ได้นำเข้าคุณสามารถใช้py_compileและcompileallโมดูล

py_compileโมดูลด้วยตนเองสามารถรวบรวมโมดูลใด ๆ วิธีหนึ่งคือการใช้py_compile.compileฟังก์ชันในโมดูลนั้นแบบโต้ตอบ:

>>> import py_compile
>>> py_compile.compile('abc.py')

สิ่งนี้จะเขียน. pyc ไปยังตำแหน่งเดียวกับ abc.py (คุณสามารถแทนที่ด้วยพารามิเตอร์เสริมcfile)

นอกจากนี้คุณยังสามารถรวบรวมไฟล์ทั้งหมดในไดเรกทอรีหรือไดเรกทอรีโดยอัตโนมัติโดยใช้โมดูลรวบรวม

python -m compileall

หากไม่ระบุชื่อไดเรกทอรี (ไดเรกทอรีปัจจุบันในตัวอย่างนี้) โมดูลจะรวบรวมทุกสิ่งที่พบ sys.path


6
และประโยชน์ของการคอมไพล์เพื่อรับ abc.py คืออะไร?
Saher Ahwal

@ SaaAhwal ประโยชน์อย่างหนึ่งที่ฉันคิดได้คือการตรวจสอบไวยากรณ์
ยี่เปา

20

Python (อย่างน้อยการใช้งานที่พบบ่อยที่สุดของมัน) ตามรูปแบบของการรวบรวมแหล่งต้นฉบับเพื่อรหัสไบต์แล้วตีความรหัสไบต์บนเครื่องเสมือน นี่หมายถึง (อีกครั้งการติดตั้งทั่วไป) ไม่ใช่ทั้งล่ามและผู้แปล

อย่างไรก็ตามอีกด้านหนึ่งของกระบวนการนี้คือกระบวนการรวบรวมส่วนใหญ่จะถูกซ่อนไว้ - ไฟล์. pyc นั้นเสมือนว่าเป็นแคช มันเพิ่มความเร็วในการทำงาน แต่โดยปกติคุณไม่จำเป็นต้องรับรู้เลย มันจะทำให้โมฆะโดยอัตโนมัติและโหลดซ้ำอีกครั้ง (รวบรวมซอร์สโค้ดใหม่) เมื่อจำเป็นตามการประทับเวลา / วันที่ของไฟล์

เกี่ยวกับครั้งเดียวที่ฉันเห็นปัญหาเกี่ยวกับเรื่องนี้คือเมื่อไฟล์ bytecode ที่คอมไพล์ได้รับการประทับเวลาในอนาคตซึ่งหมายความว่ามันจะดูใหม่กว่าไฟล์ต้นฉบับเสมอ เนื่องจากมันดูใหม่กว่าเดิมซอร์สไฟล์จึงไม่เคยถูกคอมไพล์ซ้ำดังนั้นไม่ว่าคุณจะเปลี่ยนแปลงอะไรพวกเขาก็ถูกเพิกเฉย ...


12

ไฟล์ Python * .py เป็นเพียงไฟล์ข้อความที่คุณเขียนโค้ดบางบรรทัด เมื่อคุณพยายามเรียกใช้ไฟล์นี้โดยใช้คำว่า "python filename.py"

คำสั่งนี้เรียกใช้ Python Virtual Machine Python Virtual Machine มี 2 องค์ประกอบคือ "compiler" และ "interpreter" ล่ามไม่สามารถอ่านข้อความในไฟล์ * .py ดังนั้นข้อความนี้จะถูกแปลงแรกเป็นรหัสไบต์ซึ่งมีการกำหนดเป้าหมายที่จะ PVM (ไม่ฮาร์ดแวร์ แต่ PVM) PVM เรียกใช้งานโค้ดไบต์นี้ ไฟล์ * .pyc ยังถูกสร้างขึ้นโดยเป็นส่วนหนึ่งของการเรียกใช้ซึ่งดำเนินการนำเข้าของคุณบนไฟล์ในเชลล์หรือในไฟล์อื่น

หากไฟล์ * .pyc นี้สร้างขึ้นแล้วทุกครั้งที่คุณเรียกใช้ / เรียกใช้ไฟล์ * .py ของคุณระบบจะโหลดไฟล์ * .pyc ของคุณโดยตรงซึ่งไม่จำเป็นต้องมีการรวบรวมใด ๆ

เมื่อสร้างไฟล์ * .pyc แล้วไม่จำเป็นต้องใช้ไฟล์ * .py เว้นแต่ว่าคุณจะแก้ไข


7

รหัส Python ต้องผ่าน 2 ขั้นตอน ขั้นตอนแรกรวบรวมรหัสเป็นไฟล์. pyc ซึ่งเป็นจริง bytecode จากนั้นไฟล์. pyc นี้ (bytecode) จะถูกตีความโดยใช้ CPython interpreter โปรดดูที่นี้การเชื่อมโยง ขั้นตอนการรวบรวมและประมวลผลโค้ดในที่นี้มีคำอธิบายอย่างง่าย

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.