Câu trả lời:
Từ "Có gì mới trong Python 2.6 - Thay đổi trình thông dịch" :
Bây giờ Python có thể được ngăn không cho ghi các tệp .pyc hoặc .pyo bằng cách cung cấp khóa -B cho trình thông dịch Python hoặc bằng cách đặt biến môi trường PYTHONDONTWRITEBYTECODE trước khi chạy trình thông dịch. Cài đặt này có sẵn cho các chương trình Python dưới dạng
sys.dont_write_bytecode
biến và mã Python có thể thay đổi giá trị để sửa đổi hành vi của trình thông dịch.
Cập nhật 2010-11-27: Python 3.2 giải quyết vấn đề làm lộn xộn các thư mục nguồn với .pyc
các tệp bằng cách giới thiệu một __pycache__
thư mục con đặc biệt , xem Có gì mới trong Python 3.2 - Thư mục kho lưu trữ PYC .
export PYTHONDONTWRITEBYTECODE=1
import sys
sys.dont_write_bytecode = True
site-packages/usercustomize.py
để áp dụng điều này cho tất cả các tập lệnh của bạn. Đối với tôi, thư mục này là $HOME/.local/lib/python2.6/site-pacakges/usercustomize.py
. Cf. docs.python.org/2/tutorial/ trộm
import sys; sys.dont_write_bytecode = True
Thực sự có một cách để làm điều đó trong Python 2.3+, nhưng đó là một chút bí truyền. Tôi không biết nếu bạn nhận ra điều này, nhưng bạn có thể làm như sau:
$ unzip -l /tmp/example.zip
Archive: /tmp/example.zip
Length Date Time Name
-------- ---- ---- ----
8467 11-26-02 22:30 jwzthreading.py
-------- -------
8467 1 file
$ ./python
Python 2.3 (#1, Aug 1 2003, 19:54:32)
>>> import sys
>>> sys.path.insert(0, '/tmp/example.zip') # Add .zip file to front of path
>>> import jwzthreading
>>> jwzthreading.__file__
'/tmp/example.zip/jwzthreading.py'
Theo thư viện zipimport :
Bất kỳ tệp nào cũng có thể có trong kho lưu trữ ZIP, nhưng chỉ các tệp .py và .py [co] có sẵn để nhập. Nhập ZIP của các mô-đun động (.pyd, .so) không được phép. Lưu ý rằng nếu tệp lưu trữ chỉ chứa tệp .py, Python sẽ không cố gắng sửa đổi tệp lưu trữ bằng cách thêm tệp .pyc hoặc .pyo tương ứng, nghĩa là nếu tệp lưu trữ ZIP không chứa tệp .pyc, việc nhập có thể khá chậm.
Vì vậy, tất cả những gì bạn phải làm là nén các tệp lên, thêm zipfile vào sys.path của bạn và sau đó nhập chúng.
Nếu bạn đang xây dựng điều này cho UNIX, bạn cũng có thể xem xét việc đóng gói tập lệnh của mình bằng công thức này: unix zip có thể thực thi được , nhưng lưu ý rằng bạn có thể phải điều chỉnh điều này nếu bạn dự định sử dụng stdin hoặc đọc bất cứ thứ gì từ sys.args (nó có thể thực hiện mà không gặp quá nhiều rắc rối).
Theo kinh nghiệm của tôi, hiệu suất không bị ảnh hưởng quá nhiều vì điều này, nhưng bạn nên suy nghĩ kỹ trước khi nhập bất kỳ mô-đun rất lớn nào theo cách này.
Trong 2.5, không có cách nào để ngăn chặn nó, ngoại trừ các biện pháp như không cho phép người dùng ghi quyền truy cập vào thư mục.
Tuy nhiên, trong python 2.6 và 3.0, có thể có một cài đặt trong mô-đun sys có tên "dont_write_bytecode" có thể được đặt để triệt tiêu điều này. Điều này cũng có thể được đặt bằng cách chuyển tùy chọn "-B" hoặc đặt biến môi trường "PYTHONDONTWRITEBYTECODE"
Bạn có thể thiết lập sys.dont_write_bytecode = True
trong nguồn của mình, nhưng đó sẽ phải nằm trong tệp python đầu tiên được tải. Nếu bạn thực hiện python somefile.py
thì bạn sẽ không nhận được somefile.pyc
.
Khi bạn cài đặt một tiện ích bằng cách sử dụng setup.py
và entry_points=
bạn sẽ thiết lập sys.dont_write_bytecode
trong tập lệnh khởi động. Vì vậy, bạn không thể dựa vào tập lệnh khởi động "mặc định" được tạo bởi setuptools.
Nếu bạn khởi động Python với tệp python làm đối số, bạn có thể chỉ định -B
:
python -B somefile.py
somefile.pyc
dù sao cũng sẽ không được tạo, nhưng cũng không có .pyc
tệp nào cho các tệp khác được nhập.
Nếu bạn có một số tiện ích myutil
và bạn không thể thay đổi điều đó, nó sẽ không chuyển -B cho trình thông dịch python. Chỉ cần bắt đầu bằng cách đặt biến môi trường PYTHONDONTWRITEBYTECODE
:
PYTHONDONTWRITEBYTECODE=x myutil
Tôi có một số trường hợp thử nghiệm trong bộ thử nghiệm và trước khi tôi chạy bộ thử nghiệm trong Mac Terminal như thế này:
python LoginSuite.py
Chạy lệnh theo cách này thư mục của tôi đã được điền với các tệp .pyc. Tôi đã thử phương pháp đã nêu dưới đây và nó đã giải quyết được vấn đề:
python -B LoginSuite.py
Phương pháp này hoạt động nếu bạn đang nhập các trường hợp kiểm thử vào bộ kiểm tra và chạy bộ trên dòng lệnh.
Bắt đầu với Python 3.8, bạn có thể sử dụng biến môi trường PYTHONPYCACHEPREFIX
để xác định thư mục bộ đệm cho Python.
Từ các tài liệu Python:
Nếu điều này được đặt, Python sẽ ghi các tệp .pyc vào cây thư mục nhân bản tại đường dẫn này, thay vì trong pycache thư mục trong cây nguồn. Điều này tương đương với việc chỉ định tùy chọn -X pycache_prefix = PATH.
Thí dụ
Nếu bạn thêm dòng sau ./profile
vào Linux của bạn :
export PYTHONPYCACHEPREFIX="$HOME/.cache/cpython/"
Python sẽ không tạo các __pycache__
thư mục gây phiền nhiễu trong thư mục dự án của bạn, thay vào đó, nó sẽ đặt tất cả chúng vào~/.cache/cpython/
Bạn có thể làm cho các thư mục mà các mô-đun của bạn tồn tại ở chế độ chỉ đọc cho người dùng mà trình thông dịch Python đang chạy.
Tôi không nghĩ có một lựa chọn thanh lịch hơn. PEP 304 dường như là một nỗ lực để giới thiệu một tùy chọn đơn giản cho việc này, nhưng dường như nó đã bị bỏ rơi.
Tôi tưởng tượng có thể có một số vấn đề khác mà bạn đang cố gắng giải quyết, trong đó việc vô hiệu hóa .py [co] có vẻ là một cách giải quyết, nhưng có lẽ sẽ tốt hơn nếu tấn công bất cứ vấn đề ban đầu nào thay vào đó.
Giải pháp cho ipython 6.2.1 using python 3.5.2
(Đã thử nghiệm trên Ubuntu 16.04 và Windows 10):
Ipython
không tôn trọng %env PYTHONDONTWRITEBYTECODE =1
nếu được đặt trong trình ipython
thông dịch hoặc trong khi khởi động ~/.ipython/profile-default/startup/00-startup.ipy
. Thay vì sử dụng những điều sau đây trong~.ipython/profile-default/startup/00-startup.py
import sys
sys.dont_write_bytecode=True
Theo tôi biết python sẽ biên dịch tất cả các mô-đun bạn "nhập". Tuy nhiên, python sẽ KHÔNG biên dịch tập lệnh python bằng cách sử dụng: "python script.py" (tuy nhiên, nó sẽ biên dịch bất kỳ mô-đun nào mà tập lệnh nhập).
Các câu hỏi thực sự là tại sao bạn không muốn python biên dịch các mô-đun? Bạn có thể có thể tự động hóa một cách để làm sạch những thứ này nếu chúng cản trở.
.pyc
các tập tin mã byte cũ . Vì một số lý do, khi tôi thay đổi lớp / mô-đun, .pyc
tệp không được cập nhật. Vì vậy, khi tôi nhập nó sau khi thay đổi.py
tệp, nó vẫn sẽ sử dụng .pyc
tệp, dẫn đến lỗi