Cách sử dụng tệp pyc trong python

Tạo cây cú pháp trừu tượng (AST) cho nguồn Python có hai giai đoạn. Cái đầu tiên tạo một cây cú pháp đơn giản (SST) và một cây phạm vi. Giai đoạn thứ hai chuyển đổi SST thành cây khung Triển khai Ngôn ngữ Truffle

Đối với việc chuyển đổi, cây phạm vi nó cần. Cây phạm vi chứa các vị trí phạm vi cho các định nghĩa hàm và biến cũng như thông tin về phạm vi. Cây cú pháp đơn giản chứa các nút phản ánh nguồn. So sánh SST và cây khung triển khai ngôn ngữ, SST nhỏ hơn nhiều. Nó chỉ chứa các nút đại diện cho nguồn theo cách đơn giản. Một nút SST thường được dịch sang nhiều nút Khung triển khai ngôn ngữ

Cây cú pháp đơn giản có thể được tạo theo hai cách. với phân tích cú pháp ANTLR hoặc giải tuần tự hóa từ tệp *.pyc thích hợp. Nếu không có tệp .pyc thích hợp cho một nguồn, thì nguồn đó sẽ được phân tích cú pháp bằng ANTLR. Nếu logic nhập tiêu chuẩn của Python tìm thấy một tệp .pyc thích hợp, thì nó sẽ chỉ kích hoạt quá trình giải tuần tự hóa SST và cây phạm vi từ nó

Quá trình khử lưu huỳnh nhanh hơn nhiều so với phân tích cú pháp nguồn bằng ANTLR và chỉ cần khoảng 30% thời gian mà ANTLR cần. Tất nhiên, lần nhập tệp mới đầu tiên chậm hơn một chút – bên cạnh việc phân tích cú pháp bằng ANTLR, logic nhập thư viện chuẩn Python tuần tự hóa đối tượng mã kết quả thành tệp .pyc, trong trường hợp của chúng tôi có nghĩa là SST và cây phạm vi được đánh số thứ tự như vậy

Tạo và quản lý tệp pyc

Các tệp .pyc được tạo tự động bởi thời gian chạy GraalVM Python khi không tìm thấy hoặc tìm thấy tệp .pyc không hợp lệ khớp với tệp
MAGIC_NUMBER
source text
binary data - scope tree
binary data - simple syntax tree
4 mong muốn

Khi tệp nguồn Python (mô-đun) được nhập lần đầu tiên trong quá trình thực thi, tệp .pyc thích hợp sẽ được tạo tự động. Nếu cùng một mô-đun được nhập lại, thì tệp .pyc đã tạo sẽ được sử dụng. Điều đó có nghĩa là không có tệp .pyc nào cho tệp nguồn chưa được thực thi (nhập). Việc tạo các tệp .pyc được thực hiện hoàn toàn thông qua API Hệ thống tệp để người nhúng có thể quản lý quyền truy cập hệ thống tệp

Mỗi lần thực hiện tiếp theo của tập lệnh sẽ sử dụng lại các tệp .pyc hiện có hoặc sẽ tạo một tệp mới. Tệp .pyc được tạo lại nếu dấu thời gian hoặc mã băm của tệp nguồn ban đầu bị thay đổi. Mã băm chỉ được tạo dựa trên nguồn Python bằng cách gọi

MAGIC_NUMBER
source text
binary data - scope tree
binary data - simple syntax tree
8, là mã băm JDK trên mảng byte tệp nguồn, được tính bằng
MAGIC_NUMBER
source text
binary data - scope tree
binary data - simple syntax tree
9

Các tệp .pyc cũng được tạo lại nếu một số ma thuật trong trình phân tích cú pháp Python bị thay đổi. Số ma thuật được mã hóa cứng trong nguồn Python và người dùng không thể thay đổi (tất nhiên trừ khi người dùng đó có quyền truy cập vào mã byte của Python)

Các nhà phát triển thời gian chạy Python của GraalVM thay đổi số ma thuật khi định dạng của SST hoặc dữ liệu nhị phân cây phạm vi bị thay đổi. Đây là một chi tiết triển khai, do đó, số ma thuật không nhất thiết phải tương ứng với phiên bản thời gian chạy Python của GraalVM (giống như trong CPython). Số ma thuật của pyc là một chức năng của mã Java thời gian chạy Python cụ thể đang chạy

Lưu ý rằng nếu bạn sử dụng tệp .pyc, bạn sẽ cần cho phép ghi quyền truy cập vào thời gian chạy Python của GraalVM ít nhất khi chuyển đổi phiên bản hoặc thay đổi mã nguồn ban đầu. Nếu không, việc tạo lại các tệp nguồn sẽ không thành công và mỗi lần nhập sẽ có chi phí truy cập vào tệp .pyc cũ, phân tích cú pháp mã, đánh số thứ tự và cố gắng (và không thành công) để ghi ra một tệp .pyc mới

Tệp *.pyc không bao giờ bị xóa bởi thời gian chạy Python của GraalVM, chỉ được tạo lại. Nó được tạo lại khi tệp nguồn thích hợp bị thay đổi (dấu thời gian của lần sửa đổi cuối cùng hoặc mã băm của nội dung) hoặc số ma thuật của trình phân tích cú pháp triển khai Python thay đổi. Các thay đổi về số ma thuật sẽ được thông báo trong ghi chú phát hành để người nhúng hoặc quản trị viên hệ thống có thể xóa các tệp .pyc cũ khi nâng cấp

Cấu trúc thư mục được tạo cho các tệp .pyc trông như thế này

top_folder
    __pycache__
         sourceA.graalpython.pyc
         sourceB.graalpython.pyc
    sourceA.py
    sourceB.py
    sub_folder
        __pycache__
            sourceX.graalpython.pyc
        sourceX.py

Theo mặc định, thư mục

>>> def add(x, y):
..   return x+y
...
>>> add.__code__.co_code
b'\x01\x00\x00\x02[]K\xbf\xd1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 ...'
7 được tạo ở cùng cấp thư mục với tệp mã nguồn và trong thư mục này, tất cả các tệp .pyc từ cùng thư mục được lưu trữ. Thư mục này có thể lưu trữ .pyc tệp được tạo bằng các phiên bản Python khác nhau (bao gồm, e. g. , CPython), vì vậy người dùng có thể thấy các tệp kết thúc bằng .pyc0 chẳng hạn

Việc triển khai hiện tại cũng bao gồm một bản sao của văn bản gốc trong tệp .pyc. Đây là một tối ưu hóa hiệu suất nhỏ để bạn có thể tạo một đối tượng .pyc2 với đường dẫn đến tệp nguồn ban đầu, nhưng bạn không cần phải đọc tệp .pyc3 ban đầu, giúp tăng tốc quá trình lấy cây khung Thực thi Ngôn ngữ (chỉ cần một tệp là . Cấu trúc của tệp .pyc4 là thế này

MAGIC_NUMBER
source text
binary data - scope tree
binary data - simple syntax tree

Lưu ý rằng các tệp .pyc không phải là phương tiện hiệu quả để ẩn mã nguồn thư viện Python khỏi mã khách, vì nguồn ban đầu vẫn có thể được khôi phục. Ngay cả khi nguồn bị bỏ qua, cây cú pháp vẫn chứa đủ thông tin để dịch ngược thành mã nguồn một cách dễ dàng

SST tuần tự hóa và cây phạm vi cũng được lưu trữ trong một đối tượng Python .pyc6, như nội dung của thuộc tính .pyc7 (chứa mã byte trên CPython). Ví dụ

>>> def add(x, y):
..   return x+y
...
>>> add.__code__.co_code
b'\x01\x00\x00\x02[]K\xbf\xd1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 ...'

Các tệp .pyc phần lớn được quản lý tự động bởi thời gian chạy theo cách tương thích với CPython. Giống như trên CPython, có các tùy chọn để chỉ định vị trí của chúng và liệu chúng có nên được viết hay không và cả hai tùy chọn này đều có thể được thay đổi bằng mã khách

Việc tạo các tệp *.pyc có thể được kiểm soát theo cách tương tự như trên CPython (c. f. https. // tài liệu. con trăn. org/3/sử dụng/dòng lệnh. html)

  • Trình khởi chạy Python của GraalVM (_______140) đọc biến môi trường
    MAGIC_NUMBER
    source text
    binary data - scope tree
    binary data - simple syntax tree
    
    41. 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
  • Tùy chọn dòng lệnh trình khởi chạy
    MAGIC_NUMBER
    source text
    binary data - scope tree
    binary data - simple syntax tree
    
    43, nếu được cung cấp, có tác dụng tương tự như trên
  • Mã ngôn ngữ khách có thể thay đổi thuộc tính
    MAGIC_NUMBER
    source text
    binary data - scope tree
    binary data - simple syntax tree
    
    44 của mô-đun tích hợp sẵn
    MAGIC_NUMBER
    source text
    binary data - scope tree
    binary data - simple syntax tree
    
    45 trong thời gian chạy để thay đổi hành vi cho các lần nhập tiếp theo
  • Trình khởi chạy đọc biến môi trường
    MAGIC_NUMBER
    source text
    binary data - scope tree
    binary data - simple syntax tree
    
    46. Nếu được đặt, thư mục
    >>> def add(x, y):
    ..   return x+y
    ...
    >>> add.__code__.co_code
    b'\x01\x00\x00\x02[]K\xbf\xd1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 ...'
    
    7 sẽ được tạo tại đường dẫn được chỉ ra bởi tiền tố và bản sao cấu trúc thư mục của cây nguồn sẽ được tạo theo yêu cầu để chứa các tệp .pyc
  • Mã ngôn ngữ khách có thể thay đổi thuộc tính
    MAGIC_NUMBER
    source text
    binary data - scope tree
    binary data - simple syntax tree
    
    49 của mô-đun
    MAGIC_NUMBER
    source text
    binary data - scope tree
    binary data - simple syntax tree
    
    45 trong thời gian chạy để thay đổi vị trí cho các lần nhập tiếp theo

Vì trình nhúng không thể sử dụng các biến môi trường hoặc tùy chọn CPython để giao tiếp các tùy chọn này với việc triển khai Python của GraalVM, nên các tùy chọn này được cung cấp dưới dạng các tùy chọn ngôn ngữ này

  • *.pyc1 - tương đương với
    MAGIC_NUMBER
    source text
    binary data - scope tree
    binary data - simple syntax tree
    
    43 hoặc
    MAGIC_NUMBER
    source text
    binary data - scope tree
    binary data - simple syntax tree
    
    41
  • *.pyc4 - tương đương với
    MAGIC_NUMBER
    source text
    binary data - scope tree
    binary data - simple syntax tree
    
    46

Lưu ý rằng ngữ cảnh Python sẽ không cho phép ghi tệp .pyc theo mặc định. Trình khởi chạy

MAGIC_NUMBER
source text
binary data - scope tree
binary data - simple syntax tree
40 kích hoạt nó theo mặc định, nhưng nếu điều này là mong muốn trong trường hợp sử dụng nhúng, thì cần cẩn thận để đảm bảo rằng vị trí
>>> def add(x, y):
..   return x+y
...
>>> add.__code__.co_code
b'\x01\x00\x00\x02[]K\xbf\xd1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 ...'
7 được quản lý đúng cách và các tệp ở vị trí đó được bảo vệ khỏi thao tác giống như các tệp nguồn
MAGIC_NUMBER
source text
binary data - scope tree
binary data - simple syntax tree
4

Cũng lưu ý rằng để nâng cấp các nguồn ứng dụng lên thời gian chạy Python của GraalVM Enteprise, các tệp .pyc cũ phải được trình nhúng xóa theo yêu cầu

Cân nhắc về Bảo mật

Việc tuần tự hóa SST và cây phạm vi được viết tay và trong quá trình giải tuần tự hóa, không thể tải các lớp khác ngoài Nút SST. Tuần tự hóa Java hoặc các khung khác không được sử dụng để tuần tự hóa các đối tượng Java. Lý do chính là hiệu suất, nhưng điều này có tác dụng là không thể tải lớp bằng tệp .pyc được tạo độc hại

Tất cả các hoạt động của tệp (lấy dữ liệu, dấu thời gian và ghi tệp .pyc2) được thực hiện thông qua API Hệ thống tệp. Trình nhúng có thể sửa đổi tất cả các hoạt động này bằng phương tiện tùy chỉnh (e. g. , chỉ đọc) .pyc3 triển khai. Trình nhúng cũng có thể vô hiệu hóa hiệu quả việc tạo tệp .pyc bằng cách vô hiệu hóa quyền I/O cho thời gian chạy Python của GraalVM

Nếu tệp .pyc không thể đọc được, vị trí của chúng không thể ghi được. Nếu dữ liệu tuần tự hóa hoặc số ma thuật của tệp .pyc bị hỏng theo bất kỳ cách nào, quá trình giải tuần tự hóa không thành công và chúng tôi chỉ phân tích lại tệp

MAGIC_NUMBER
source text
binary data - scope tree
binary data - simple syntax tree
4. Điều này đi kèm với một điểm hiệu suất nhỏ chỉ dành cho việc phân tích cú pháp các mô-đun, điều này không đáng kể đối với hầu hết các ứng dụng (miễn là ứng dụng thực sự hoạt động bên cạnh việc tải mã Python)

Chúng tôi có thể nhập tệp PYC bằng Python không?

Tóm lại, để nhập tệp biên dịch Python (e. g. mô-đun. pyc), chỉ cần đặt nó trong cùng thư mục chứa nguồn (e. mô-đun g. py) và đảm bảo rằng không có tệp nguồn tương ứng (mô-đun. py trong ví dụ của chúng tôi) ở đó. Sau đó, mô-đun nhập thông thường sẽ hoạt động trơn tru

Làm cách nào để sử dụng pyc trong Python?

tệp pyc được tạo bởi trình thông dịch Python khi một *. tệp py được nhập vào bất kỳ tệp python nào khác . Các *. tệp pyc chứa “mã byte được biên dịch” của mô-đun/chương trình đã nhập để có thể bỏ qua “bản dịch” từ mã nguồn sang mã byte trong các lần nhập tiếp theo của *.

Tại sao Python tạo tệp PYC?

. pyc files are created by the Python interpreter khi một. tệp py được nhập . Chúng chứa "mã byte đã biên dịch" của mô-đun/chương trình đã nhập để quá trình "dịch" từ mã nguồn sang mã byte (chỉ cần thực hiện một lần) có thể được bỏ qua trong các lần nhập tiếp theo nếu.

Tệp Python PYC là gì?

Tệp PYC là tệp đầu ra đã biên dịch được tạo từ mã nguồn được viết bằng ngôn ngữ lập trình Python . Khi tệp PY được chạy bằng trình thông dịch Python, nó sẽ được chuyển thành mã byte để thực thi.