ฉันจะสร้างไฟล์. pyc ด้วยตนเองจากไฟล์. py ได้อย่างไร


128

ด้วยเหตุผลบางอย่างฉันไม่สามารถพึ่งพาคำสั่ง "นำเข้า" ของ Python เพื่อสร้างไฟล์. pyc โดยอัตโนมัติ

มีวิธีการใช้ฟังก์ชั่นดังต่อไปนี้หรือไม่?

def py_to_pyc(py_filepath, pyc_filepath):
    ...

คำตอบ:


241

คุณสามารถใช้compileallในอาคารผู้โดยสาร คำสั่งต่อไปนี้จะไปซ้ำในไดเรกทอรีย่อยและทำไฟล์ pyc สำหรับไฟล์หลามทั้งหมดที่พบ compileallโมดูลเป็นส่วนหนึ่งของห้องสมุดมาตรฐานหลามดังนั้นคุณจึงไม่จำเป็นต้องติดตั้งพิเศษอะไรที่จะใช้มัน วิธีนี้ใช้ได้ผลเหมือนกับ python2 และ python3

python -m compileall .

4
นี้ควรจะเป็นคำตอบที่ได้รับการยอมรับ --at น้อยในความต้องการของฉันที่จะรวบรวม .py * ทั้งหมดลงใน .pyc *: ซ้ำ :)
swdev

1
เป็นไปได้ไหมที่จะแจกจ่ายไฟล์ PYC ที่มีไลบรารี่ทั้งหมดที่ใช้? ดังนั้นผู้ใช้ไม่ต้องติดตั้งพวกเขาเพียงแค่เรียกใช้ไฟล์ PYC ฉันรู้ว่าในจาวานี้เป็นไปได้โดยใช้ JARs มีวิธีใดที่คล้ายกันสำหรับ Python?
D.Snap

ฉันได้ยินเรื่องเกี่ยวกับเมตาไฟล์ใน Python ด้วย รวบรวมนี้ยังสร้างแคชบางอย่าง? ถ้าไม่คำสั่งสำหรับสิ่งนั้นคืออะไร? เนื่องจากผู้ใช้ไม่ได้รับอนุญาตให้เขียนไปยังไดเรกทอรี lib และฉันต้องการที่จะเร่งความเร็วสิ่งต่าง ๆ ที่นี่ ... PS ยังดูที่-Oธงสำหรับการรวบรวม bytecode (.pyo ไฟล์ iso .pyc)
danger89

สิ่งที่เกี่ยวกับ decompiling?
Sajuuk

1
ระวังด้วยคำสั่งนี้ ฉันบังเอิญทำcompileallในโฟลเดอร์แพ็คเกจเว็บไซต์ของฉันและมันทำให้ทุกอย่างยุ่งเหยิง
อเล็กซ์

58

คุณสามารถรวบรวมไฟล์แต่ละไฟล์จากบรรทัดคำสั่งด้วย:

python -m compileall <file_1>.py <file_n>.py

55

เป็นเวลานานแล้วที่ฉันใช้ Python ครั้งล่าสุด แต่ฉันเชื่อว่าคุณสามารถใช้py_compile:

import py_compile
py_compile.compile("file.py")

8
คุณอาจต้องการรวมพารามิเตอร์ตัวที่สองซึ่งกำหนดไฟล์เอาต์พุต มิฉะนั้นจะมีค่าเริ่มต้นเป็นอย่างอื่น__pycache__/file.cpython-32.pycและคุณจะได้รับเป็นค่าตอบแทน
rvighne

46

ฉันพบหลายวิธีในการรวบรวมสคริปต์ไพ ธ อนลงใน bytecode

  1. ใช้py_compileใน terminal:

    python -m py_compile File1.py File2.py File3.py ...

    -m ระบุชื่อโมดูลที่จะรวบรวม

    หรือสำหรับการรวบรวมไฟล์แบบโต้ตอบ

    python -m py_compile -
    File1.py
    File2.py
    File3.py
       .
       .
       .
  2. การใช้py_compile.compile:

    import py_compile
    py_compile.compile('YourFileName.py')
  3. การใช้py_compile.main():

    มันรวบรวมไฟล์หลายไฟล์ในเวลาเดียวกัน

    import py_compile
    py_compile.main(['File1.py','File2.py','File3.py'])

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

    หรือถ้าคุณผ่าน['-']หลักก็สามารถรวบรวมไฟล์แบบโต้ตอบ

  4. การใช้compileall.compile_dir():

    import compileall
    compileall.compile_dir(direname)

    มันรวบรวมไฟล์ Python ทุกไฟล์ที่มีอยู่ในไดเรกทอรีที่ให้มา

  5. การใช้compileall.compile_file():

    import compileall
    compileall.compile_file('YourFileName.py')

ดูลิงค์ด้านล่าง:

https://docs.python.org/3/library/py_compile.html

https://docs.python.org/3/library/compileall.html


หนึ่งในการแก้ไขขนาดเล็กก็คือชื่อโมดูลที่คุณโหลดpy_compileและcompileallไม่ได้หรือpy_compile.py compileall.pyในคำอื่น ๆ ที่ควรจะเป็นหรือpython3 -m py_compile PYTHON_FILENAME python3 -m compileall PYTHON_FILES_DIRECTORY
Devy

17

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


compileallไม่ได้รวมตรรกะในการข้ามไฟล์ที่มีไฟล์ที่เกี่ยวข้อง.pycเป็นปัจจุบันอยู่ใช่ไหม?
Kyle Strand

2
@KyleStrand compileallทำการข้ามไฟล์ที่มีข้อมูลล่าสุดแล้ว.pyc(ทดสอบด้วย Python 2.7.11)
Eponymous

@Eponymous น่าสนใจ ไม่แน่ใจว่าทำไมฉันจึงคิดอย่างอื่น ขอบคุณสำหรับการตรวจสอบ
Kyle Strand

6

ใน Python2 คุณสามารถใช้:

python -m compileall <pythonic-project-name>

ซึ่งทำให้คอมไพล์ทั้งหมด.pyถึง.pycในโครงการซึ่งมีโฟลเดอร์ย่อย


ใน Python3 คุณสามารถใช้:

python3 -m compileall <pythonic-project-name>

ซึ่งทำให้รวบรวมทั้งหมด.pyไปยัง__pycache__โฟลเดอร์ในโครงการที่มีโฟลเดอร์ย่อย

หรือด้วยสีน้ำตาลจากโพสต์นี้ :

คุณสามารถบังคับใช้เค้าโครง.pycไฟล์เดียวกันในโฟลเดอร์เช่นเดียวกับใน Python2 โดยใช้:

python3 -m compileall -b <pythonic-project-name>

ตัวเลือกนี้-bจะทริกเกอร์เอาท์พุทของ.pycไฟล์ไปยังตำแหน่งดั้งเดิม (เช่นเดียวกับใน Python2)


3

เพื่อให้ตรงกับความต้องการของคำถามดั้งเดิม (เส้นทางที่มาและเส้นทางปลายทาง) รหัสควรเป็นเช่นนั้น:

import py_compile
py_compile.compile(py_filepath, pyc_filepath)

หากรหัสอินพุตมีข้อผิดพลาดจะมีการยกข้อยกเว้นpy_compile.PyCompileError


1

มีสองวิธีในการทำเช่นนี้

  1. บรรทัดคำสั่ง
  2. ใช้โปรแกรมหลาม

หากคุณกำลังใช้บรรทัดคำสั่งใช้python -m compileall <argument>เพื่อรวบรวมรหัสหลามเพื่อรหัสหลามไบนารี Ex:python -m compileall -x ./*

หรือ คุณสามารถใช้รหัสนี้เพื่อรวบรวมห้องสมุดของคุณเป็นรหัสไบต์

import compileall
import os

lib_path = "your_lib_path"
build_path = "your-dest_path"

compileall.compile_dir(lib_path, force=True, legacy=True)

def compile(cu_path):
    for file in os.listdir(cu_path):
        if os.path.isdir(os.path.join(cu_path, file)):
            compile(os.path.join(cu_path, file))
        elif file.endswith(".pyc"):
            dest = os.path.join(build_path, cu_path ,file)
            os.makedirs(os.path.dirname(dest), exist_ok=True)
            os.rename(os.path.join(cu_path, file), dest)

compile(lib_path)

ดูที่☞ docs.python.orgเพื่อดูเอกสารโดยละเอียด

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