Bagaimana saya dapat secara manual menghasilkan file .pyc dari file .py

128

Untuk beberapa alasan, saya tidak dapat bergantung pada pernyataan "impor" Python untuk menghasilkan file .pyc secara otomatis

Apakah ada cara untuk mengimplementasikan fungsi sebagai berikut?

def py_to_pyc(py_filepath, pyc_filepath):
    ...
zJay
sumber

Jawaban:

241

Anda bisa menggunakannya compilealldi terminal. Perintah berikut akan secara rekursif masuk ke sub direktori dan membuat file pyc untuk semua file python yang ditemukannya. The compileall Modul merupakan bagian dari python perpustakaan standar, sehingga Anda tidak perlu menginstal apa pun untuk menggunakannya. Cara kerjanya persis sama untuk python2 dan python3.

python -m compileall .
Marwan Alsabbagh
sumber
4
Ini harus menjadi jawaban yang diterima - setidaknya dalam kebutuhan saya untuk mengkompilasi semua * .py ke * .pyc: rekursif :)
swdev
1
Apakah mungkin untuk mendistribusikan file PYC yang berisi semua perpustakaan yang digunakan? Jadi pengguna tidak harus menginstalnya, jalankan saja file PYC, saya tahu di java ini dimungkinkan menggunakan JAR apakah ada metode serupa untuk Python?
D.Snap
Saya juga mendengar sesuatu tentang file meta dengan Python. Compileall ini juga membangun beberapa cache? Jika tidak, apa perintah untuk itu ?? Karena pengguna akhir tidak memiliki izin menulis ke direktori lib. Dan saya ingin mempercepat di sini ... PS. lihat juga -Oflagnya, untuk kompilasi bytecode (.pyo file iso .pyc).
hazard89
bagaimana dengan dekompilasi?
Sajuuk
1
hati-hati dengan perintah ini. Saya tidak sengaja melakukan compileallpada folder situs-paket saya dan itu mengacaukan segalanya
Alex
58

Anda dapat mengkompilasi file individual dari baris perintah dengan:

python -m compileall <file_1>.py <file_n>.py
derrend
sumber
55

Sudah lama sejak saya terakhir menggunakan Python, tapi saya yakin Anda bisa menggunakan py_compile:

import py_compile
py_compile.compile("file.py")
Mike Bailey
sumber
8
Anda mungkin ingin memasukkan parameter kedua, yang menentukan file output. Kalau tidak, itu default ke sesuatu seperti __pycache__/file.cpython-32.pycdan Anda mendapatkan itu sebagai nilai kembali.
rvighne
46

Saya menemukan beberapa cara untuk mengkompilasi skrip python ke bytecode

  1. Menggunakan py_compiledi terminal:

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

    -m menentukan nama modul yang akan dikompilasi.

    Atau, untuk kompilasi file interaktif

    python -m py_compile -
    File1.py
    File2.py
    File3.py
       .
       .
       .
  2. Menggunakan py_compile.compile:

    import py_compile
    py_compile.compile('YourFileName.py')
  3. Menggunakan py_compile.main():

    Ini mengkompilasi beberapa file sekaligus.

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

    Daftar dapat tumbuh selama yang Anda inginkan. Atau, Anda dapat dengan jelas melewati daftar file dalam nama file utama atau bahkan dalam argumen baris perintah.

    Atau, jika Anda meneruskan ['-']main maka dapat mengkompilasi file secara interaktif.

  4. Menggunakan compileall.compile_dir():

    import compileall
    compileall.compile_dir(direname)

    Ini mengkompilasi setiap file Python tunggal yang ada di direktori yang disediakan.

  5. Menggunakan compileall.compile_file():

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

Lihatlah tautan di bawah ini:

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

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

Abhishek Kashyap
sumber
Satu koreksi kecil adalah bahwa nama modul yang Anda muat adalah py_compiledan compileallTIDAK py_compile.pyatau compileall.py. Dengan kata lain, seharusnya python3 -m py_compile PYTHON_FILENAMEatau python3 -m compileall PYTHON_FILES_DIRECTORY.
Devy
17

Saya akan menggunakan compileall . Ini berfungsi baik dari skrip dan dari baris perintah. Ini adalah modul / alat yang sedikit lebih tinggi daripada py_compile yang telah disebutkan yang juga digunakan secara internal.

Pekka Klärck
sumber
compilealltidak termasuk logika untuk melewatkan file yang .pycfile terkait sudah mutakhir, bukan?
Kyle Strand
2
@KyleStrand compileallmelewatkan file yang sudah memiliki yang terbaru .pyc(diuji dengan Python 2.7.11)
Eponim
@ Sangat Menarik. Tidak yakin mengapa saya berpikir sebaliknya. Terima kasih sudah memeriksa.
Kyle Strand
6

Di Python2 Anda bisa menggunakan:

python -m compileall <pythonic-project-name>

yang merek mengkompilasi semua .pyuntuk .pycdalam proyek yang berisi subfolder.


Di Python3 Anda bisa menggunakan:

python3 -m compileall <pythonic-project-name>

yang membuat kompilasi semua .pyke __pycache__folder dalam proyek yang berisi subfolder.

Atau dengan browning dari pos ini :

Anda bisa menerapkan tata letak .pycfile yang sama di folder seperti di Python2 dengan menggunakan:

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

Opsi -bmemicu output .pycfile ke lokasi-legacy mereka (yaitu sama seperti di Python2).

Benyamin Jafari
sumber
3

Untuk mencocokkan persyaratan pertanyaan asli (jalur sumber dan jalur tujuan) kodenya harus seperti itu:

import py_compile
py_compile.compile(py_filepath, pyc_filepath)

Jika kode input memiliki kesalahan maka pengecualian py_compile.PyCompileError dinaikkan.

ababak
sumber
1

Ada dua cara untuk melakukan ini

  1. Garis komando
  2. Menggunakan program python

Jika Anda menggunakan baris perintah gunakan python -m compileall <argument>untuk mengkompilasi kode python ke kode biner python. Ex:python -m compileall -x ./*

Atau, Anda dapat menggunakan kode ini untuk mengkompilasi perpustakaan Anda ke dalam byte-code.

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)

lihat ☞ docs.python.org untuk dokumentasi terperinci

Prashant
sumber