Bạn biết rằng bạn có thể biên dịch và chạy chương trình Python chỉ bằng một lệnh PYTHON duy nhất trong dấu nhắc lệnh của DOS. Hãy cho chúng tôi biết cách tạo hoặc chuyển đổi tệp mã byte Python. pyc từ tệp nguồn. py và xem nó trên bảng điều khiển bằng cách sử dụng hướng dẫn về python vào phút cuối này
Các từ mã byte và mã byte được sử dụng thay thế cho nhau
Hãy nhớ rằng với tư cách là lập trình viên hoặc nhà phát triển, bạn nên phân phối mã cho người dùng cuối. Người dùng cuối chạy tệp mã byte do bạn chia sẻ trong Hệ thống của anh ấy với Môi trường thời gian chạy Python tương thích
Ghi chú. Chia sẻ tệp mã byte an toàn hơn so với chia sẻ tệp thực thi. Virus không làm hỏng các tệp mã byte
1. Cách tạo tệp mã byte Python. pyc
Chúng tôi sử dụng mô-đun tích hợp Python " py_compile " để tạo tệp mã byte.
Thực hiện theo các bước bên dưới để tạo tệp mã Python Byte ". pyc". Cuối cùng, chúng tôi cố gắng chạy. pyc sử dụng cùng một lệnh PYTHON
Bước 1 . Tạo một chương trình Python mẫu với tên "generate_bytecode. py". Nhập mã sau.
print['Generating Byte Code File. .pyc from .py file']
Bước 2 . Trong dấu nhắc lệnh của DOS, hãy nhập lệnh bên dưới để tạo tệp Byte-Code.
C:\Python> python -m py_compile generate_bytecode.py
Bước 3 . Kiểm tra thư mục hiện tại cho thư mục " __pycache__ ". Python tạo một tệp mã byte có tên PROGNAME. cpython-xx. pyc . Ở đây, xx là phiên bản Python. Đối với ví dụ trên, tên của tệp mã Byte là generate_bytecode. cpython-39. pyc . Bạn có thể phân phối này. tệp pyc để sử dụng sẵn.
Bước 4 . Để chạy. pyc, chỉ cần sử dụng lệnh PYTHON trong dấu nhắc lệnh như hình bên dưới.
C:\Python\__pycache__> python generate_bytecode.cpyton-39.pyc Generating Byte Code File. .pyc from .py file C:\Python\__pycache__>
Lưu ý rằng người dùng cuối có thể đặt cái này. pyc trong bất kỳ thư mục nào và chạy để có được đầu ra giống như dự định của nhà phát triển
2. Cách xem tệp Mã byte Python trên Bảng điều khiển
Thực tế là không cần xem Mã Byte Python. Nó chỉ dành cho mục đích kiến thức. Bạn nên sử dụng mô-đun tích hợp Python " dis " để hoàn thành tác vụ này. Mô-đun DIS đại diện cho Disassembler. Hãy để chúng tôi xem mã byte bằng lệnh bên dưới.
C:\Python> python -m dis generate_bytecode.py 1 0 LOAD_NAME 0 [print] 2 LOAD_CONST 0 ['Generating Byte Code File. .pyc from .py file'] 4 CALL_FUNCTION 1 6 POP_TOP 8 LOAD_CONST 1 [None] 10 RETURN_VALUE
Quan sát rằng bạn đang cung cấp một. py vào lệnh python. Bạn có thể tìm thấy các hướng dẫn mã byte như LOAD_NAME, LOAD_CONST, CALL_FUNCTION, POP_TOP, BINARY_ADD, RETURN_VALUE, v.v. bên trong mã
Python là một ngôn ngữ thông dịch. Phiên dịch có nghĩa là mã nguồn được dịch sang mã máy khi chương trình chạy. Nhưng đó là một sự đơn giản hóa tổng thể
Python về cơ bản có bốn bước để chạy mã nguồn của bạn. lexer, trình phân tích cú pháp, trình biên dịch và trình thông dịch. Lexer và trình phân tích cú pháp là hiển nhiên. Nó được sử dụng để tạo cây cú pháp trừu tượng. Trình biên dịch có thể gây sốc cho hầu hết mọi người
Giống như hầu hết các ngôn ngữ thông dịch khác, ban đầu Python biên dịch mã nguồn do chúng ta viết sang định dạng trung gian
$ time python3 a.py8
Hello World!real 0m0.038s
user 0m0.025s
sys 0m0.010s
Mã byte là một tập hợp hướng dẫn cấp thấp được gọi là chứa tập hợp hướng dẫn có thể được giải thích bởi
$ time python3 a.py9. Như bạn có thể thấy có cả trình biên dịch và trình thông dịch
Hello World!real 0m0.038s
user 0m0.025s
sys 0m0.010s
Nhưng lý do Python được gọi là ngôn ngữ thông dịch là vì hầu hết công việc được thực hiện bởi trình thông dịch. Có thể đọc và hiểu bytecode sẽ giúp bạn tối ưu code cũng như hiểu Python hơn
Chúng tôi có một tập lệnh đơn giản
$ ls __pycache__/
hello.cpython-38.pyc
0def hello[]:
print[“Hello World!”]hello[]
Hãy thử chạy tập lệnh
$ time python3 a.py
Hello World!real 0m0.038s
user 0m0.025s
sys 0m0.010s
Khi bạn chạy tệp, thỉnh thoảng bạn sẽ thấy thư mục con
$ ls __pycache__/
hello.cpython-38.pyc
1. Nếu bạn nhìn vào bên trong nó, bạn sẽ thấy tên tệp mã nguồn của mình với phần mở rộng $ ls __pycache__/
hello.cpython-38.pyc
2$ ls __pycache__/
hello.cpython-38.pyc
Trong trường hợp bạn không nhìn thấy thư mục. Bạn có thể tự biên dịch tệp bằng CLI
C:\Python> python -m py_compile generate_bytecode.py2
Nếu bạn chạy lại nó, bạn sẽ thấy thời gian thực thi sẽ được cải thiện một chút vì Python không phải phân tích lại mã nguồn của chúng tôi mỗi khi nó chạy
C:\Python> python -m py_compile generate_bytecode.py3
Bạn thậm chí có thể chạy trực tiếp tệp
$ ls __pycache__/
hello.cpython-38.pyc
3C:\Python> python -m py_compile generate_bytecode.py5
Tháo rời mã byte
Sử dụng
$ ls __pycache__/
hello.cpython-38.pyc
4 để xem nội dung của $ ls __pycache__/
hello.cpython-38.pyc
5 sẽ cung cấp cho bạn các giá trị rác. Chúng ta có thể thấy bytecode theo nghĩa đen của mã bằng cách sử dụng $ ls __pycache__/
hello.cpython-38.pyc
6 để chuyển mã nguồn thành AST ban đầu, sau đó là $ ls __pycache__/
hello.cpython-38.pyc
7. Do đó, mã được biên dịch sau này có thể được chạy bởi $ ls __pycache__/
hello.cpython-38.pyc
8 hoặc $ ls __pycache__/
hello.cpython-38.pyc
9C:\Python\__pycache__> python generate_bytecode.cpyton-39.pyc Generating Byte Code File. .pyc from .py file C:\Python\__pycache__>2
Ở đây,
C:\Python> python -m py_compile generate_bytecode.py20 ngụ ý rằng mã nguồn chứa nhiều câu lệnh Python
Bạn có thể xem mã byte cho các giá trị đã được biên dịch bằng cách sử dụng
$ ls __pycache__/
hello.cpython-38.pyc
7C:\Python\__pycache__> python generate_bytecode.cpyton-39.pyc Generating Byte Code File. .pyc from .py file C:\Python\__pycache__>5
Để xem
C:\Python> python -m py_compile generate_bytecode.py22 theo nghĩa đen, chúng ta có thể sử dụng
$ ls __pycache__/
hello.cpython-38.pyc
7C:\Python\__pycache__> python generate_bytecode.cpyton-39.pyc Generating Byte Code File. .pyc from .py file C:\Python\__pycache__>8
Hãy cố gắng hiểu điều này. Chúng tôi biết rằng mỗi lệnh trong Python bao gồm hai byte ở định dạng sau
C:\Python\__pycache__> python generate_bytecode.cpyton-39.pyc Generating Byte Code File. .pyc from .py file C:\Python\__pycache__>9
C:\Python> python -m py_compile generate_bytecode.py24 là lệnh một byte. Trong khi
C:\Python> python -m py_compile generate_bytecode.py25 là đối số dành riêng cho hướng dẫn
$ time python3 a.py0
Hello World!real 0m0.038s
user 0m0.025s
sys 0m0.010s
Một điều sẽ ngay lập tức đến với bạn khi bạn thấy điều này là nó chẳng có ý nghĩa gì đối với con người chúng ta. Vì vậy, chúng tôi có một thứ gọi là
C:\Python> python -m py_compile generate_bytecode.py26, tên thân thiện với con người của
C:\Python> python -m py_compile generate_bytecode.py27. Để tìm tên, chúng ta có thể kiểm tra danh sách
C:\Python> python -m py_compile generate_bytecode.py28 trong mô-đun
C:\Python> python -m py_compile generate_bytecode.py29
$ time python3 a.py1
Hello World!real 0m0.038s
user 0m0.025s
sys 0m0.010s
Thay vì tổ chức opcode và oparg để xem hướng dẫn mã byte Chúng ta có thể phân tích trực tiếp đối tượng python thành dạng mã byte có thể đọc được bằng cách sử dụng mô-đun
C:\Python> python -m py_compile generate_bytecode.py30
$ time python3 a.py2
Hello World!real 0m0.038s
user 0m0.025s
sys 0m0.010s
Ở đây, số 2 ở bên trái biểu thị số dòng
đồng thuộc tính
Có rất nhiều thuộc tính quan trọng mang theo
C:\Python> python -m py_compile generate_bytecode.py31. Ví dụ
$ time python3 a.py3
Hello World!real 0m0.038s
user 0m0.025s
sys 0m0.010s
C:\Python> python -m py_compile generate_bytecode.py
32 là một tuple chứa các thuộc tính và phương thức toàn cục được sử dụng bên trong phạm vi. Hàm in là một hàm toàn cục đang được sử dụng trong hàm hiện tại nên chúng ta có thể thấy nó trong bộ dữ liệuC:\Python> python -m py_compile generate_bytecode.py
33C:\Python> python -m py_compile generate_bytecode.py
34 là bộ chứa các tên biến cục bộ được sử dụng trong hàm. Không có biến nào được khai báo trong hàm nên bộ dữ liệu trốngC:\Python> python -m py_compile generate_bytecode.py
35 Nó sẽ trả về các chữ được sử dụng bởi bytecode. Trong hàm hello, giá trị theo nghĩa đen duy nhất mà chúng ta thấy làC:\Python> python -m py_compile generate_bytecode.py
36. Python thêm Không làm một trong các tham số trả về mặc định cho hàm. Điều này sẽ cho phép python xử lý trong trường hợp không tìm thấy câu lệnh return
Có co_attributes khác mà bạn có thể kiểm tra chúng bằng cách sử dụng
$ time python3 a.py4
Hello World!real 0m0.038s
user 0m0.025s
sys 0m0.010s
Để lấy thông tin về các thuộc tính, bạn có thể xem chuỗi tài liệu này
$ time python3 a.py5
Hello World!real 0m0.038s
user 0m0.025s
sys 0m0.010s
Bây giờ hãy quay lại opcode. Đây là hướng dẫn mà máy ảo python sẽ thực thi chức năng xin chào của chúng tôi
C:\Python> python -m py_compile generate_bytecode.py
37 yêu cầu python trả về phần tử vị trí thứ 0 trongC:\Python> python -m py_compile generate_bytecode.py
33 và đẩy nó vào ngăn xếp đánh giá. Trong trường hợp này là chức năng inC:\Python> python -m py_compile generate_bytecode.py
39 sẽ lấy giá trị theo nghĩa đen ở chỉ mục 1 củaC:\Python> python -m py_compile generate_bytecode.py
50 và đẩy nó lên trên cùng. Giá trị làC:\Python> python -m py_compile generate_bytecode.py
51C:\Python> python -m py_compile generate_bytecode.py
52 yêu cầu python gọi hàm. Nó sẽ bật 1 đối số vị trí từ ngăn xếp. Bên dưới các đối số là đối tượng có thể gọi được. Tôi gọi đối tượng có thể gọi được bằng các đối số đã bật và đẩy giá trị trả vềC:\Python> python -m py_compile generate_bytecode.py
53 loại bỏ đỉnh ngăn xếp mà trong trường hợp hiện tại là chức năng của chúng tôiC:\Python> python -m py_compile generate_bytecode.py
54 sẽ thêm phần tử vị trí o từC:\Python> python -m py_compile generate_bytecode.py
55 là Không có vào giá trị cao nhất của ngăn xếpC:\Python> python -m py_compile generate_bytecode.py
56 sẽ trả về đỉnh ngăn xếp cho người gọi hàm
Như bạn có thể nhận thấy, các hướng dẫn mã byte của Python bao gồm thao tác đánh giá ngăn xếp của khung ngăn xếp cuộc gọi hiện tại. Chúng tôi sẽ nhanh chóng lướt qua máy ảo python để hiểu lý do
Cần phải hiểu rằng mã byte có thể không phổ biến giữa nhiều phiên bản Python. Tôi đang sử dụng Python3. 8 cho bài viết của tôi. Bạn có thể tìm hiểu về mã byte cụ thể của phiên bản tại đây
Máy ảo Python
Cpython sử dụng máy ảo dựa trên ngăn xếp. Nó đơn giản và mạnh mẽ. Không có đăng ký. Thay vào đó, chúng ta có thể thêm
C:\Python> python -m py_compile generate_bytecode.py57 một phần tử vào
C:\Python> python -m py_compile generate_bytecode.py58 của ngăn xếp hoặc
C:\Python> python -m py_compile generate_bytecode.py59 nó từ
C:\Python> python -m py_compile generate_bytecode.py58. Chúng tôi có
C:\Python\__pycache__> python generate_bytecode.cpyton-39.pyc Generating Byte Code File. .pyc from .py file C:\Python\__pycache__>21 là ngăn xếp chính cho chương trình Python. Nó có một mục gọi là
C:\Python\__pycache__> python generate_bytecode.cpyton-39.pyc Generating Byte Code File. .pyc from .py file C:\Python\__pycache__>22 cho mỗi lệnh gọi hàm đang hoạt động. Đáy ngăn xếp là điểm vào của chương trình
Mỗi lần gọi hàm sẽ thêm một khung mới vào ngăn xếp và mỗi khi hàm gọi trả về, nó sẽ bật lên khung. Trong Python, chúng ta có thể dễ dàng truy cập các khung này bằng mô-đun
C:\Python\__pycache__> python generate_bytecode.cpyton-39.pyc Generating Byte Code File. .pyc from .py file C:\Python\__pycache__>23
$ time python3 a.py6
Hello World!real 0m0.038s
user 0m0.025s
sys 0m0.010s
Kiểm tra trả lại một
C:\Python\__pycache__> python generate_bytecode.cpyton-39.pyc Generating Byte Code File. .pyc from .py file C:\Python\__pycache__>24 được gọi là
C:\Python\__pycache__> python generate_bytecode.cpyton-39.pyc Generating Byte Code File. .pyc from .py file C:\Python\__pycache__>25. Nó bao gồm
C:\Python\__pycache__> python generate_bytecode.cpyton-39.pyc Generating Byte Code File. .pyc from .py file C:\Python\__pycache__>26
Ghi chú. Chúng tôi đang thấy
C:\Python\__pycache__> python generate_bytecode.cpyton-39.pyc Generating Byte Code File. .pyc from .py file C:\Python\__pycache__>27 vì chúng tôi đang sử dụng thiết bị đầu cuối
Khung hiện tại sẽ luôn ở trên cùng để bạn có thể truy cập khung hiện tại bằng cách sử dụng
C:\Python\__pycache__> python generate_bytecode.cpyton-39.pyc Generating Byte Code File. .pyc from .py file C:\Python\__pycache__>28
$ time python3 a.py7
Hello World!real 0m0.038s
user 0m0.025s
sys 0m0.010s
Bạn có thể nhận thêm thông tin về khung bằng các thuộc tính đối tượng khung. để biết thêm thông tin tham khảo tại đây
Sự kết luận
Để bài viết ngắn gọn, chúng tôi xin kết thúc tại đây. Còn rất nhiều thứ còn lại nhưng với chừng này bạn có thể bắt đầu khám phá mã byte python
Học cách đọc và viết mã byte Python sẽ giúp bạn hiểu Python hơn và giúp bạn tối ưu hóa mã của mình
Ngoài ra, đây là bước khởi đầu để hiểu cách thức hoạt động của máy ảo. Điều này là dành cho hôm nay. Tôi đã thêm các liên kết hữu ích để học thêm