Làm cách nào tôi có thể tự tạo tệp .pyc từ tệp .py


128

Vì một số lý do, tôi không thể phụ thuộc vào câu lệnh "nhập" của Python để tự động tạo tệp .pyc

Có cách nào để thực hiện một chức năng như sau không?

def py_to_pyc(py_filepath, pyc_filepath):
    ...

Câu trả lời:


241

Bạn có thể sử dụng compilealltrong thiết bị đầu cuối. Lệnh sau sẽ đi đệ quy vào các thư mục con và tạo các tệp pyc cho tất cả các tệp python mà nó tìm thấy. Các compileall Module này là một phần của thư viện chuẩn trăn, do đó bạn không cần phải cài đặt bất cứ điều gì thêm để sử dụng nó. Điều này hoạt động chính xác theo cách tương tự cho python2 và python3.

python -m compileall .

4
Đây phải là câu trả lời được chấp nhận - ít nhất là trong nhu cầu của tôi để biên dịch tất cả * .py thành * .pyc: đệ quy :)
swdev

1
Có thể phân phối tệp PYC chứa tất cả các thư viện được sử dụng không? Vì vậy, người dùng không phải cài đặt chúng, chỉ cần chạy tệp PYC, tôi biết trong java điều này có thể sử dụng JAR có phương pháp tương tự nào cho Python không?
D.Snap 15/03/2016

Tôi cũng đã nghe một vài điều về các tệp meta trong Python. Compileall này cũng xây dựng một số bộ đệm? Nếu không, lệnh đó là gì ?? Vì người dùng cuối không có quyền ghi vào thư mục lib. Và tôi muốn tăng tốc mọi thứ ở đây ... PS. cũng hãy xem -Ocờ, để biên dịch mã byte (.pyo iso .pyc).
nguy hiểm89

Còn dịch ngược thì sao?
Sajuuk

1
hãy cẩn thận với lệnh này Tôi đã vô tình làm một compileallthư mục trên gói trang web của tôi và nó đã làm rối tung mọi thứ
Alex

58

Bạn có thể biên dịch (các) tệp riêng lẻ từ dòng lệnh với:

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

55

Đã được một thời gian kể từ lần cuối tôi sử dụng Python, nhưng tôi tin rằng bạn có thể sử dụng py_compile:

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

8
Bạn có thể muốn bao gồm tham số thứ hai, xác định tệp đầu ra. Mặt khác, nó mặc định là một cái gì đó giống như __pycache__/file.cpython-32.pycvà bạn lấy đó làm giá trị trả về.
rvighne

46

Tôi đã tìm thấy một số cách để biên dịch các kịch bản python thành mã byte

  1. Sử dụng py_compiletrong thiết bị đầu cuối:

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

    -m chỉ định tên mô-đun sẽ được biên dịch.

    Hoặc, để biên dịch tương tác các tập tin

    python -m py_compile -
    File1.py
    File2.py
    File3.py
       .
       .
       .
  2. Sử dụng py_compile.compile:

    import py_compile
    py_compile.compile('YourFileName.py')
  3. Sử dụng py_compile.main():

    Nó biên dịch một số tập tin tại một thời điểm.

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

    Danh sách có thể phát triển miễn là bạn muốn. Ngoài ra, rõ ràng bạn có thể chuyển một danh sách các tệp trong tên chính hoặc thậm chí tên tệp trong dòng lệnh args.

    Hoặc, nếu bạn truyền ['-']vào chính thì nó có thể biên dịch các tệp tương tác.

  4. Sử dụng compileall.compile_dir():

    import compileall
    compileall.compile_dir(direname)

    Nó biên dịch mọi tệp Python duy nhất có trong thư mục được cung cấp.

  5. Sử dụng compileall.compile_file():

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

Hãy xem các liên kết dưới đây:

https://docs.python.org/3/l Library / py_compile.html

https://docs.python.org/3/l Library / compileall.html


Một điều chỉnh nhỏ là tên mô-đun bạn đang tải là py_compilecompileallKHÔNG py_compile.pyhoặc compileall.py. Nói cách khác, nó nên python3 -m py_compile PYTHON_FILENAMEhoặc python3 -m compileall PYTHON_FILES_DIRECTORY.
Devy

17

Tôi sẽ sử dụng compileall . Nó hoạt động độc đáo cả từ kịch bản và từ dòng lệnh. Đó là mô-đun / công cụ cấp cao hơn một chút so với py_compile đã được đề cập mà nó cũng sử dụng nội bộ.


compileallkhông bao gồm logic để bỏ qua các tệp mà .pyctệp tương ứng đã được cập nhật, phải không?
Kyle Strand

2
@KyleStrand compileallkhông bỏ qua các tệp đã được cập nhật .pyc(đã được thử nghiệm với Python 2.7.11)
Eponymous

@Eponymous Thú vị. Không chắc tại sao tôi lại nghĩ khác. Cảm ơn vì đã kiểm tra.
Kyle Strand

6

Trong Python2 bạn có thể sử dụng:

python -m compileall <pythonic-project-name>

mà biên dịch tất cả .pythành .pyctrong dự án có chứa các thư mục con.


Trong Python3 bạn có thể sử dụng:

python3 -m compileall <pythonic-project-name>

mà biên dịch tất cả .pyvào các __pycache__thư mục trong dự án có chứa các thư mục con.

Hoặc với màu nâu từ bài đăng này :

Bạn có thể thực thi cùng bố cục các .pyctệp trong các thư mục như trong Python2 bằng cách sử dụng:

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

Tùy chọn -bkích hoạt đầu ra của .pyccác tệp đến các vị trí kế thừa của chúng (tức là giống như trong Python2).


3

Để phù hợp với các yêu cầu câu hỏi ban đầu (đường dẫn nguồn và đường dẫn đích), mã phải như thế:

import py_compile
py_compile.compile(py_filepath, pyc_filepath)

Nếu mã đầu vào có lỗi thì ngoại lệ py_compile.PyCompileError được đưa ra.


1

Có hai cách để làm điều này

  1. Dòng lệnh
  2. Sử dụng chương trình python

Nếu bạn đang sử dụng dòng lệnh, hãy sử dụng python -m compileall <argument>để biên dịch mã python thành mã nhị phân python. Ví dụ:python -m compileall -x ./*

Hoặc, Bạn có thể sử dụng mã này để biên dịch thư viện của mình thành mã byte.

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)

nhìn vào ☞ docs.python.org để biết tài liệu chi tiết

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.