__Pycache__ là gì?


651

Theo những gì tôi hiểu, bộ đệm là một tệp được mã hóa của các tệp tương tự.

Chúng ta làm gì với __pycache__thư mục? Có phải đó là những gì chúng tôi cung cấp cho mọi người thay vì mã nguồn của chúng tôi? Có phải nó chỉ là dữ liệu đầu vào của tôi? Thư mục này tiếp tục được tạo, nó dùng để làm gì?


29
"Có phải đó là những gì chúng tôi cung cấp cho mọi người thay vì mã nguồn của chúng tôi?" - Không, bạn cung cấp cho họ mã nguồn trong một gói có thể cài đặt đẹp để dễ sử dụng.
Lennart Regebro

79
Chưa có ai đề cập đến, nhưng định nghĩa về bộ nhớ cache của bạn rất kỳ quái. Cache khá đơn giản là một thành phần lưu trữ dữ liệu để các yêu cầu trong tương lai cho dữ liệu đó có thể được phục vụ nhanh hơn .
Ricardo Cruz


1
Python 3.8bạn có thể sử dụng biến môi trường để thay đổi vị trí cho các thư mục bộ đệm gây phiền nhiễu: stackoverflow.com/a/57414308/1612318
Rotareti

Bộ nhớ cache là thứ giữ một bản sao của công cụ trong trường hợp bạn cần lại, để tiết kiệm bạn phải quay lại bản gốc để lấy nó. Nó được thiết kế để nhanh hơn so với đi đến nơi ban đầu. Nó có thể nhanh hơn bởi vì nó không phải xử lý trước hoặc biên dịch thông tin. Hoặc nó có thể được lưu trữ nhanh hơn, ví dụ bộ đệm đĩa trong RAM hoặc bộ đệm web trên đĩa cục bộ. Bản chất của nó không được mã hóa (mặc dù đôi khi có thể như vậy) và không phải lúc nào cũng là "tệp của các tệp tương tự" - đó có thể là tệp, tải tệp, khối RAM, v.v.
rjmunro

Câu trả lời:


518

Khi bạn chạy một chương trình trong python, trình thông dịch sẽ biên dịch nó thành mã byte trước (đây là một sự đơn giản hóa) và lưu trữ nó trong __pycache__thư mục. Nếu bạn nhìn vào đó, bạn sẽ thấy một loạt các tệp chia sẻ tên của các tệp .py trong thư mục dự án của bạn, chỉ các tiện ích mở rộng của chúng sẽ là .pyc hoặc .pyo. Đây là các phiên bản được biên dịch bằng mã byte và được tối ưu hóa bởi các tệp chương trình của bạn.

Là một lập trình viên, bạn hầu như có thể bỏ qua nó ... Tất cả chỉ là làm cho chương trình của bạn bắt đầu nhanh hơn một chút. Khi tập lệnh của bạn thay đổi, chúng sẽ được biên dịch lại và nếu bạn xóa các tệp hoặc toàn bộ thư mục và chạy lại chương trình của bạn, chúng sẽ xuất hiện lại (trừ khi bạn đặc biệt ngăn chặn hành vi đó)

Nếu bạn đang sử dụng cpython (phổ biến nhất, vì đó là cách triển khai tham chiếu) và bạn không muốn thư mục đó, thì bạn có thể chặn nó bằng cách bắt đầu trình thông dịch với cờ -B, ví dụ

python -B foo.py

Một tùy chọn khác, như được lưu ý bởi tcaswell, là đặt biến môi trường PYTHONDONTWRITEBYTECODE thành bất kỳ giá trị nào (theo trang man của python, bất kỳ "chuỗi không trống" nào).


48
Bạn cũng có thể thêm biến môi trường PYTHONDONTWRITEBYTECODE=<any_value>để triệt tiêu nó vĩnh viễn.
Đánh dấu Tolonen

11
Chỉ cần làm rõ, đây chỉ là cho Python 3, đúng không?
Joe J

11
@JoeJ vâng, tôi nghĩ đó là sự thật. python2đặt các tệp đã biên dịch vào cùng thư mục với bản gốc, nếu tôi không nhầm.
scott_fakename

27
Một cảnh báo QUAN TRỌNG là tệp .pyc được lưu trong bộ nhớ cache sẽ được sử dụng thay vì tệp .py nếu tệp .py bị thiếu. Trong thực tế, điều này chỉ xảy ra nếu bạn xóa (hoặc đổi tên) các mô-đun, vì vậy đó không phải là một sự cố phổ biến, nhưng nếu một số thứ cứ tiếp tục ở đó, sau khi gãi đầu, hãy chạy tìm. -name * .pyc | xargs rm trên nguồn của bạn có lẽ là một phản ứng đầu tiên tốt.
yacc143

34
find . -name '*.pyc' -deleteCó, find có một cờ để xóa các tập tin đã tìm thấy, vì vậy bạn không phải sử dụng bất kỳ xargs shananigans nào
vlad-ardelean

174

__pycache__là một thư mục chứa Python 3 bytecode được biên dịch và sẵn sàng để được thực thi .

Tôi không khuyên bạn nên thường xuyên xóa các tệp này hoặc ngăn chặn việc tạo trong quá trình phát triển vì nó có thể ảnh hưởng đến hiệu suất. Chỉ cần có một lệnh đệ quy sẵn sàng (xem bên dưới) để dọn dẹp khi cần vì mã byte có thể trở nên cũ kỹ trong các trường hợp cạnh (xem bình luận).

Các lập trình viên Python thường bỏ qua mã byte. Thật vậy __pycache__*.pyclà những dòng phổ biến để xem trong .gitignorecác tập tin. Mã byte không có nghĩa là để phân phối và có thể được tháo rời bằng cách sử dụng dismô-đun .


Nếu bạn đang sử dụng OS X, bạn có thể dễ dàng ẩn tất cả các thư mục này trong dự án của mình bằng cách chạy lệnh sau từ thư mục gốc của dự án.

find . -name '__pycache__' -exec chflags hidden {} \;

Thay thế __pycache__bằng*.pyc Python 2.

Điều này đặt cờ trên tất cả các thư mục (tệp .pyc) thông báo cho Finder / Textmate 2 để loại trừ chúng khỏi danh sách. Điều quan trọng là mã byte ở đó, nó chỉ bị ẩn.

Chạy lại lệnh nếu bạn tạo các mô-đun mới và muốn ẩn mã byte mới hoặc nếu bạn xóa các tệp mã byte ẩn.


Trên Windows, lệnh tương đương có thể là (không được kiểm tra, tập lệnh bó được chào đón):

dir * /s/b | findstr __pycache__ | attrib +h +s +r

Điều này cũng giống như đi qua các thư mục ẩn dự án bằng cách nhấp chuột phải> ẩn ...


Chạy thử nghiệm đơn vị là một kịch bản (nhiều hơn trong các bình luận) trong đó việc xóa các *.pyctệp và __pycache__thư mục thực sự hữu ích. Tôi sử dụng các dòng sau trong tôi ~/.bash_profilevà chỉ chạy clđể dọn dẹp khi cần thiết.

alias cpy='find . -name "__pycache__" -delete'
alias cpc='find . -name "*.pyc"       -delete'
...
alias cl='cpy && cpc && ...'

Điều này sẽ không được hoàn tác mỗi khi bạn chạy mã?
Holloway

2
@DoTheEvo: đơn giản là nó không được tạo, vì vậy không có tăng tốc vào lần tới khi mô-đun được tải. Không có lỗi được nêu ra.
Petr Viktorin

7
Đây không phải là một câu trả lời tốt. Người hỏi muốn biết những tập tin này để làm gì. Câu trả lời này nói rằng "đừng lo lắng về điều đó" và sau đó làm cho chúng biến mất.
thú vị khác

36
Hoàn toàn bận tâm xóa những điều này : nó không phải là vô nghĩa. Python sẽ vui vẻ không phát hiện các thay đổi tệp và chạy một tệp bộ đệm trong nhiều trường hợp, đẩy bạn lên tường với "tại sao f vẫn không hoạt động, tôi đã thay đổi mã, tại sao nó vẫn thất bại trong các cuộc gọi không tồn tại" vô nghĩa. Đặc biệt trong các khung kiểm tra, pycache theo mặc định là tồi tệ nhất.
Mike 'Pomax' Kamermans

2
Tôi sẽ không đồng ý với lời khuyên này để "không bận tâm xóa các tệp này" - đã thấy đề xuất này nhiều lần, gần đây nhất là "Làm thế nào để Python" ("thủ thuật mã byte")
Louis Maddox

38

Một __pycache__thư mục được tạo khi bạn sử dụng dòng:

import file_name

hoặc cố gắng lấy thông tin từ một tập tin khác mà bạn đã tạo. Điều này làm cho nó nhanh hơn một chút khi chạy chương trình của bạn lần thứ hai để mở tệp khác.


27

Cập nhật câu trả lời từ hơn 3,7 tài liệu:

Để tăng tốc độ tải các mô-đun, Python lưu trữ phiên bản đã biên dịch của từng mô-đun trong __pycache__thư mục dưới tên module.version.pyc, trong đó phiên bản mã hóa định dạng của tệp đã biên dịch; nó thường chứa số phiên bản Python. Ví dụ: trong bản phát hành CPython 3.3, phiên bản được biên dịch của spam.py sẽ được lưu trong bộ nhớ cache dưới dạng __pycache__/spam.cpython-33.pyc. Quy ước đặt tên này cho phép các mô-đun được biên dịch từ các bản phát hành khác nhau và các phiên bản khác nhau của Python để cùng tồn tại.

Nguồn: https://docs.python.org/3/tutorial/modules.html#compiled-python-files

Đó là, thư mục này được tạo bởi Python và tồn tại để làm cho các chương trình của bạn chạy nhanh hơn. Không nên cam kết kiểm soát nguồn và cùng tồn tại trong hòa bình với mã nguồn địa phương của bạn.


__pycache__là một thư mục chứa các tệp bộ nhớ cache bytecode được tạo tự động bởi python, cụ thể là python được biên dịch, hoặc .pyc, các tệp. Bạn có thể tự hỏi tại sao Python, một ngôn ngữ "diễn giải", có bất kỳ tệp được biên dịch nào cả. Câu hỏi SO này giải quyết rằng (và chắc chắn đáng đọc câu trả lời này ).

Các tài liệu python đi sâu hơn về chính xác cách thức hoạt động và lý do tại sao nó tồn tại:

  • Nó được thêm vào python 3.2 vì hệ thống duy trì .pyccác tệp trong cùng một thư mục hiện có gây ra nhiều vấn đề khác nhau, chẳng hạn như khi một chương trình được chạy với các trình thông dịch Python của các phiên bản khác nhau. Để biết thông số tính năng đầy đủ, xem PEP 3174 .

5

từ các mô-đun hướng dẫn python chính thức

Để tăng tốc độ tải các mô-đun, Python lưu trữ phiên bản đã biên dịch của từng mô-đun trong __pycache__thư mục dưới tên module.version.pyc, trong đó phiên bản mã hóa định dạng của tệp đã biên dịch; nó thường chứa số phiên bản Python. Ví dụ: trong bản phát hành CPython 3.6, phiên bản được biên dịch của spam.py sẽ được lưu trong bộ nhớ cache dưới dạng __pycache__/spam.cpython-36.pyc.

từ Câu hỏi thường gặp về lập trình tài liệu Python

Khi một mô-đun được nhập lần đầu tiên (hoặc khi tệp nguồn đã thay đổi kể từ khi tệp được biên dịch hiện tại được tạo), một tệp .pyc chứa mã được biên dịch sẽ được tạo trong __pycache__thư mục con của thư mục chứa .pytệp. Các .pyctập tin sẽ có một tên tập tin bắt đầu với cái tên tương tự như các .pytập tin, và kết thúc với .pyc, với một thành phần trung lưu mà phụ thuộc vào nhị phân python cụ thể mà tạo ra nó.


5

Việc thực thi tập lệnh python sẽ khiến mã byte được tạo trong bộ nhớ và được giữ cho đến khi chương trình được tắt. Trong trường hợp một mô-đun được nhập, để có thể sử dụng lại nhanh hơn, Python sẽ tạo bộ đệm .pyc (PYC là tệp 'Python' 'Compiled') trong đó mã byte của mô-đun được nhập vào được lưu trữ. Ý tưởng là tăng tốc độ tải các mô-đun python bằng cách tránh biên dịch lại (biên dịch một lần, chạy chính sách nhiều lần) khi chúng được nhập lại.

Tên của tệp giống như tên mô-đun. Phần sau dấu chấm ban đầu cho biết việc triển khai Python đã tạo bộ đệm (có thể là CPython) theo sau là số phiên bản của nó.


3

Trình thông dịch python biên dịch tệp script * .py và lưu kết quả của quá trình biên dịch vào __pycache__ thư mục.

Khi dự án được thực hiện lại, nếu trình thông dịch xác định rằng tập lệnh * .py chưa được sửa đổi, nó sẽ bỏ qua bước biên dịch và chạy tệp * .pyc được tạo trước đó được lưu trữ trong __pycache__thư mục.

Khi dự án phức tạp, bạn có thể làm cho thời gian chuẩn bị trước khi dự án được chạy ngắn hơn. Nếu chương trình quá nhỏ, bạn có thể bỏ qua điều đó bằng cách sử dụng python -B abc.pyvới Btùy chọn.


3

Phiên bản Python 2.x sẽ có .pyc khi trình thông dịch biên dịch mã.

Python Phiên bản 3.x sẽ có __pycache__ khi trình thông dịch biên dịch mã.

alok@alok:~$ ls
module.py  module.pyc  __pycache__  test.py
alok@alok:~$

2

Trong phiên bản 3.2 trở lên, Python lưu các tệp mã byte được biên dịch .pyc trong thư mục con có tên __pycache__trong thư mục chứa các tệp nguồn của bạn với tên tệp xác định phiên bản Python đã tạo ra chúng (ví dụ: script.cpython-33.pyc)


Làm cách nào tôi có thể tránh việc tạo thư mục " pycache " và tất cả .pyc phải được đặt tên giống như tệp .py?
Ashwani

1

Khi bạn nhập một mô-đun ,

import file_name

Python lưu mã byte được biên dịch trong __pycache__thư mục để các lần nhập trong tương lai có thể sử dụng trực tiếp, thay vì phải phân tích cú pháp và biên dịch lại nguồn.

Nó không làm điều đó chỉ đơn thuần là chạy một tập lệnh, chỉ khi một tập tin được nhập.

(Các phiên bản trước được sử dụng để lưu trữ mã byte được lưu trong bộ nhớ cache dưới dạng tệp .pyc nằm trong cùng thư mục với tệp .py, nhưng bắt đầu trong Python 3, chúng được chuyển sang thư mục con để làm cho mọi thứ gọn gàng hơn.)

PYTHONDONTWRITEBYTECODE ---> Nếu điều này được đặt thành một chuỗi không trống, Python sẽ không cố ghi các tệp .pyc khi nhập mô-đun nguồn. Điều này tương đương với việc chỉ định tùy chọn -B.

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.