2008-09-30 37 views

Trả lời

262

Từ "What’s New in Python 2.6 - Interpreter Changes":

Python bây giờ có thể được ngăn chặn từ viết pyc hoặc các tập tin .pyo bởi cung cấp công tắc -B cho trình thông dịch Python hoặc bằng cách đặt biến số PYTHONDONTWRITEBYTECODE môi trường trước khi chạy thông dịch viên . Cài đặt này có sẵn cho các chương trình Python dưới dạng biến số sys.dont_write_bytecode và Mã Python có thể thay đổi giá trị thành sửa đổi hành vi của thông dịch viên.

Cập nhật 2010-11-27: Python 3.2 địa chỉ các vấn đề lộn xộn thư mục nguồn với .pyc file bằng cách giới thiệu một __pycache__ thư mục con đặc biệt, xem What's New in Python 3.2 - PYC Repository Directories.

+1

Ít nhất trên OS X 10.8 chạy Python 2.7 biến môi trường không có hiệu lực. – sorin

+2

Nếu bạn đang nhúng trình thông dịch (trong chương trình C++), hãy sử dụng "Py_DontWriteBytecodeFlag = 1;" trong mã nguồn của bạn.Đó là một int toàn cục được khai báo trong pydebug.h. – JimB

+2

Điều này không bao giờ hoạt động. – tar

1

Theo như 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 một tập lệnh python chạy 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 khẩu).

Câu hỏi thực sự là lý do 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 điều này nếu họ đang nhận được trong cách.

+0

của bạn tôi đã tìm thấy thường xuyên rằng có cũ bytecode 'file .pyc'. Vì một số lý do, khi tôi thay đổi lớp/mô-đun, tệp '.pyc' không được cập nhật. Vì vậy, khi tôi nhập nó sau khi thay đổi tệp '.py', nó sẽ vẫn sử dụng tệp' .pyc', dẫn đến lỗi –

1

Bạn có thể tạo 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ĩ rằng 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 điều này, nhưng nó dường như đã 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, để vô hiệu hóa .py [co] dường như là một cách giải quyết, nhưng có lẽ tốt hơn là nên tấn công bất kỳ vấn đề gốc nào này.

9

Trong 2.5, không có cách nào để ngăn chặn nó, ngoài các biện pháp như không cho phép người dùng viết quyền truy cập vào thư mục.

Trong trăn 2.6 và 3.0 tuy nhiên, có thể có cài đặt trong mô-đun sys có tên "dont_write_bytecode" có thể được đặt để chặn điều này. Đây cũng có thể được thiết lập bằng cách thông qua các "-B" tùy chọn, hoặc thiết lập các biến môi trường "PYTHONDONTWRITEBYTECODE"

22

Có thực sự là 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 tin có thể có mặt trong kho lưu trữ ZIP, nhưng chỉ tập tin. py và .py [co] có sẵn để nhập. Không cho phép nhập ZIP mô-đun động (.pyd, .so). Lưu ý rằng nếu một tệp lưu trữ chỉ chứa các 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 nén ZIP không chứa tệp .pyc, việc nhập có thể khá chậm.

Do đó, tất cả những gì bạn phải làm là nén tệp lên, thêm tệp zip vào sys.path của bạn rồi 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ách sử dụng công thức này: unix zip executable, nhưng lưu ý rằng bạn có thể phải tinh chỉnh điều này nếu bạn định sử dụng stdin hoặc đọc bất kỳ thứ gì từ sys.args CÓ THỂ được thực hiện mà không có quá nhiều rắc rối).

Trong hoạt động kinh nghiệm của tôi không bị 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 theo cách này.

91
import sys 

sys.dont_write_bytecode = True 
+8

Thao tác này không hoạt động đối với các mô-đun đã nhập –

+22

Tôi vừa thử tính năng này và nó hoạt động đối với các mô-đun đã nhập. Cụ thể, sau khi biến này được đặt, mọi thứ được nhập sau sẽ không tạo tệp pyc. Điều này thật thú vị. Cảm ơn. –

+0

Thay vì thêm điều này trong Mô-đun chính, hãy thử thêm điều này trong Tập lệnh được tham chiếu. Điều này hoạt động mát mẻ. Nhờ @te wilson – Sathy

2

Tôi có một vài trường hợp thử nghiệm trong một bộ kiểm tra và trước khi tôi đã chạy bộ ứng dụng thử nghiệm trong Mac ga như thế này:

python LoginSuite.py 

Chạy lệnh theo cách này thư mục của tôi đã được dân cư với tệp .pyc. Tôi đã thử phương pháp được nêu bên dưới và giải quyết vấn đề:

python -B LoginSuite.py 

Phương pháp này hoạt động nếu bạn nhập trường hợp thử nghiệm vào bộ kiểm tra và chạy bộ trên dòng lệnh.

6

Bạn có thể đặt sys.dont_write_bytecode = True trong nguồn của mình, nhưng điều đó 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 tiện ích bằng cách sử dụng setup.pyentry_points=, bạn sẽ đặt 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 bắt đầu với Python file python như là đối số cho mình, bạn có thể chỉ định -B:

python -B somefile.py 

somefile.pyc sẽ không được tạo ra dù sao, nhưng không có .pyc file cho các tập tin khác được nhập khẩu quá.

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 tới trình thông dịch trăn. Chỉ cần bắt đầu nó bằng cách thiết lập các biến môi trường PYTHONDONTWRITEBYTECODE:

PYTHONDONTWRITEBYTECODE=x myutil 
0

Giải pháp cho ipython 6.2.1 using python 3.5.2 (Tested trên Ubuntu 16.04 và Windows 10):

Ipython không tôn trọng %env PYTHONDONTWRITEBYTECODE =1 nếu thiết lập trong ipython thông dịch hoặc trong quá trình khởi động trong ~/.ipython/profile-default/startup/00-startup.ipy. Thay vì sử dụng sau trong ~.ipython/profile-default/startup/00-startup.py

import sys 
Sys.dont_write_bytecode=True 
Các vấn đề liên quan