Đối tượng mã

Đối tượng mã là chi tiết cấp thấp của việc triển khai CPython. Mỗi cái đại diện cho một đoạn mã thực thi chưa được ràng buộc vào một hàm.

type PyCodeObject

Cấu trúc C của các đối tượng được sử dụng để mô tả các đối tượng mã. Các trường thuộc loại này có thể thay đổi bất cứ lúc nào.

PyTypeObject PyCode_Type

Đây là một phiên bản của PyTypeObject đại diện cho code object của Python.

int PyCode_Check(PyObject *co)

Trả về true nếu cocode object. Chức năng này luôn thành công.

Py_ssize_t PyCode_GetNumFree(PyCodeObject *co)

Trả về số free (closure) variables trong một đối tượng mã.

int PyUnstable_Code_GetFirstFree(PyCodeObject *co)
Đây là API không ổn định. Nó có thể thay đổi mà không có cảnh báo trong các bản phát hành nhỏ.

Trả về vị trí của free (closure) variable đầu tiên trong đối tượng mã.

Thay đổi trong phiên bản 3.13: Đổi tên từ PyCode_GetFirstFree thành một phần của C không ổn định API. Tên cũ không được dùng nữa nhưng sẽ vẫn có sẵn cho đến khi chữ ký thay đổi lại.

PyCodeObject *PyUnstable_Code_New(int argcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, PyObject *qualname, int firstlineno, PyObject *linetable, PyObject *exceptiontable)
Đây là API không ổn định. Nó có thể thay đổi mà không có cảnh báo trong các bản phát hành nhỏ.

Trả về một đối tượng mã mới. Nếu bạn cần một đối tượng mã giả để tạo khung, thay vào đó hãy sử dụng PyCode_NewEmpty().

Vì định nghĩa của mã byte thay đổi thường xuyên nên việc gọi trực tiếp PyUnstable_Code_New() có thể liên kết bạn với một phiên bản Python chính xác.

Nhiều đối số của hàm này phụ thuộc lẫn nhau theo những cách phức tạp, có nghĩa là những thay đổi nhỏ về giá trị có thể dẫn đến việc thực thi không chính xác hoặc máy ảo gặp sự cố. Chỉ sử dụng chức năng này hết sức cẩn thận.

Thay đổi trong phiên bản 3.11: Đã thêm thông số qualnameexceptiontable.

Thay đổi trong phiên bản 3.12: Đổi tên từ PyCode_New thành một phần của C không ổn định API. Tên cũ không được dùng nữa nhưng sẽ vẫn có sẵn cho đến khi chữ ký thay đổi lại.

PyCodeObject *PyUnstable_Code_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, PyObject *qualname, int firstlineno, PyObject *linetable, PyObject *exceptiontable)
Đây là API không ổn định. Nó có thể thay đổi mà không có cảnh báo trong các bản phát hành nhỏ.

Tương tự như PyUnstable_Code_New(), nhưng có thêm "posonlyargcount" cho các đối số chỉ có vị trí. Những cảnh báo tương tự áp dụng cho PyUnstable_Code_New cũng áp dụng cho chức năng này.

Added in version 3.8: như PyCode_NewWithPosOnlyArgs

Thay đổi trong phiên bản 3.11: Đã thêm thông số qualnameexceptiontable.

Thay đổi trong phiên bản 3.12: Đổi tên thành PyUnstable_Code_NewWithPosOnlyArgs. Tên cũ không được dùng nữa nhưng sẽ vẫn có sẵn cho đến khi chữ ký thay đổi lại.

PyCodeObject *PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno)
Giá trị trả về: Tham chiếu mới.

Trả về một đối tượng mã trống mới với tên tệp, tên hàm và số dòng đầu tiên được chỉ định. Đối tượng mã kết quả sẽ tăng Exception nếu được thực thi.

int PyCode_Addr2Line(PyCodeObject *co, int byte_offset)

Trả về số dòng của lệnh xảy ra trên hoặc trước byte_offset và kết thúc sau lệnh đó. Nếu bạn chỉ cần số dòng của khung, thay vào đó hãy sử dụng PyFrame_GetLineNumber().

Để lặp lại hiệu quả số dòng trong đối tượng mã, hãy sử dụng the API described in PEP 626.

int PyCode_Addr2Location(PyObject *co, int byte_offset, int *start_line, int *start_column, int *end_line, int *end_column)

Đặt các con trỏ int đã truyền vào dòng mã nguồn và số cột cho lệnh tại byte_offset. Đặt giá trị thành 0 khi không có thông tin cho bất kỳ phần tử cụ thể nào.

Trả về 1 nếu hàm thành công và 0 nếu ngược lại.

Added in version 3.11.

PyObject *PyCode_GetCode(PyCodeObject *co)

Tương đương với mã Python getattr(co, 'co_code'). Trả về một tham chiếu mạnh tới PyBytesObject đại diện cho mã byte trong một đối tượng mã. Nếu có lỗi, NULL được trả về và xuất hiện một ngoại lệ.

Zz000zz này có thể được trình thông dịch tạo theo yêu cầu và không nhất thiết phải đại diện cho mã byte được CPython thực thi thực sự. Trường hợp sử dụng chính của hàm này là trình gỡ lỗi và trình lược tả.

Added in version 3.11.

PyObject *PyCode_GetVarnames(PyCodeObject *co)

Tương đương với mã Python getattr(co, 'co_varnames'). Trả về một tham chiếu mới tới PyTupleObject chứa tên của các biến cục bộ. Nếu có lỗi, NULL được trả về và xuất hiện một ngoại lệ.

Added in version 3.11.

PyObject *PyCode_GetCellvars(PyCodeObject *co)

Tương đương với mã Python getattr(co, 'co_cellvars'). Trả về một tham chiếu mới cho PyTupleObject chứa tên của các biến cục bộ được tham chiếu bởi các hàm lồng nhau. Nếu có lỗi, NULL được trả về và xuất hiện một ngoại lệ.

Added in version 3.11.

PyObject *PyCode_GetFreevars(PyCodeObject *co)

Tương đương với mã Python getattr(co, 'co_freevars'). Trả về một tham chiếu mới tới PyTupleObject chứa tên của free (closure) variables. Nếu có lỗi, NULL được trả về và xuất hiện một ngoại lệ.

Added in version 3.11.

int PyCode_AddWatcher(PyCode_WatchCallback callback)

Đăng ký callback làm người theo dõi đối tượng mã cho trình thông dịch hiện tại. Trả lại ID có thể được chuyển tới PyCode_ClearWatcher(). Trong trường hợp có lỗi (ví dụ: không còn ID người theo dõi), hãy trả về -1 và đặt ngoại lệ.

Added in version 3.12.

int PyCode_ClearWatcher(int watcher_id)

Trình theo dõi rõ ràng được xác định bởi watcher_id trước đây được trả về từ PyCode_AddWatcher() cho trình thông dịch hiện tại. Trả về 0 nếu thành công hoặc -1 và đặt ngoại lệ nếu có lỗi (ví dụ: nếu watcher_id đã cho chưa bao giờ được đăng ký.)

Added in version 3.12.

type PyCodeEvent

Việc liệt kê các sự kiện theo dõi đối tượng mã có thể có: - PY_CODE_EVENT_CREATE - PY_CODE_EVENT_DESTROY

Added in version 3.12.

typedef int (*PyCode_WatchCallback)(PyCodeEvent event, PyCodeObject *co)

Loại hàm gọi lại của trình theo dõi đối tượng mã.

Nếu eventPY_CODE_EVENT_CREATE thì lệnh gọi lại sẽ được gọi sau khi co được khởi tạo hoàn toàn. Nếu không, lệnh gọi lại sẽ được gọi trước khi quá trình hủy co diễn ra, do đó có thể kiểm tra trạng thái trước đó của co.

Nếu eventPY_CODE_EVENT_DESTROY, việc tham chiếu trong lệnh gọi lại đến đối tượng mã sắp bị phá hủy sẽ phục hồi nó và ngăn không cho nó được giải phóng vào lúc này. Khi đối tượng được phục hồi bị phá hủy sau đó, mọi lệnh gọi lại của người theo dõi đang hoạt động tại thời điểm đó sẽ được gọi lại.

Người dùng API này không nên dựa vào chi tiết triển khai thời gian chạy nội bộ. Những chi tiết như vậy có thể bao gồm nhưng không giới hạn ở thứ tự và thời gian chính xác của việc tạo và hủy các đối tượng mã. Mặc dù những thay đổi trong các chi tiết này có thể dẫn đến những khác biệt mà người theo dõi có thể quan sát được (bao gồm cả việc lệnh gọi lại có được gọi hay không), nhưng nó không làm thay đổi ngữ nghĩa của mã Python đang được thực thi.

Nếu lệnh gọi lại đặt ngoại lệ, nó phải trả về -1; ngoại lệ này sẽ được in dưới dạng ngoại lệ không thể xử lý được bằng PyErr_WriteUnraisable(). Nếu không nó sẽ trả về 0.

Có thể đã có một ngoại lệ đang chờ xử lý được đặt khi truy cập lệnh gọi lại. Trong trường hợp này, lệnh gọi lại sẽ trả về 0 với cùng một ngoại lệ vẫn được đặt. Điều này có nghĩa là lệnh gọi lại không được gọi bất kỳ API nào khác có thể đặt ngoại lệ trừ khi nó lưu và xóa trạng thái ngoại lệ trước, đồng thời khôi phục nó trước khi quay lại.

Added in version 3.12.

PyObject *PyCode_Optimize(PyObject *code, PyObject *consts, PyObject *names, PyObject *lnotab_obj)

Đây là chức năng soft deprecated không làm gì cả.

Trước Python 3.10, hàm này sẽ thực hiện các tối ưu hóa cơ bản cho một đối tượng mã.

Thay đổi trong phiên bản 3.10: Chức năng này bây giờ không làm gì cả.

Cờ đối tượng mã

Các đối tượng mã chứa một trường bit gồm các cờ, có thể được truy xuất dưới dạng thuộc tính Python co_flags (ví dụ: sử dụng PyObject_GetAttrString()) và được đặt bằng đối số flags thành PyUnstable_Code_New() và các hàm tương tự.

Cờ có tên bắt đầu bằng CO_FUTURE_ tương ứng với các tính năng thường được future statements chọn. Những cờ này có thể được sử dụng trong PyCompilerFlags.cf_flags. Lưu ý rằng nhiều cờ CO_FUTURE_ là bắt buộc trong các phiên bản Python hiện tại và việc đặt chúng không có hiệu lực.

Các cờ sau đây có sẵn. Để biết ý nghĩa của chúng, hãy xem tài liệu được liên kết tương đương với Python của chúng.

Lá cờ

Nghĩa

CO_OPTIMIZED

inspect.CO_OPTIMIZED

CO_NEWLOCALS

inspect.CO_NEWLOCALS

CO_VARARGS

inspect.CO_VARARGS

CO_VARKEYWORDS

inspect.CO_VARKEYWORDS

CO_NESTED

inspect.CO_NESTED

CO_GENERATOR

inspect.CO_GENERATOR

CO_COROUTINE

inspect.CO_COROUTINE

CO_ITERABLE_COROUTINE

inspect.CO_ITERABLE_COROUTINE

CO_ASYNC_GENERATOR

inspect.CO_ASYNC_GENERATOR

CO_HAS_DOCSTRING

inspect.CO_HAS_DOCSTRING

CO_METHOD

inspect.CO_METHOD

CO_FUTURE_DIVISION

không có hiệu lực (__future__.division)

CO_FUTURE_ABSOLUTE_IMPORT

không có hiệu lực (__future__.absolute_import)

CO_FUTURE_WITH_STATEMENT

không có hiệu lực (__future__.with_statement)

CO_FUTURE_PRINT_FUNCTION

không có hiệu lực (__future__.print_function)

CO_FUTURE_UNICODE_LITERALS

không có hiệu lực (__future__.unicode_literals)

CO_FUTURE_GENERATOR_STOP

không có hiệu lực (__future__.generator_stop)

CO_FUTURE_ANNOTATIONS

__future__.annotations

Thông tin bổ sung

Để hỗ trợ các phần mở rộng cấp thấp để đánh giá khung, chẳng hạn như các trình biên dịch đúng lúc bên ngoài, có thể đính kèm dữ liệu bổ sung tùy ý vào các đối tượng mã.

Các hàm này là một phần của bậc C API không ổn định: chức năng này là chi tiết triển khai CPython và API có thể thay đổi mà không có cảnh báo ngừng sử dụng.

Py_ssize_t PyUnstable_Eval_RequestCodeExtraIndex(freefunc free)
Đây là API không ổn định. Nó có thể thay đổi mà không có cảnh báo trong các bản phát hành nhỏ.

Trả về giá trị chỉ mục mờ mới được sử dụng để thêm dữ liệu vào đối tượng mã.

Bạn thường gọi hàm này một lần (mỗi trình thông dịch) và sử dụng kết quả với PyCode_GetExtraPyCode_SetExtra để thao tác dữ liệu trên các đối tượng mã riêng lẻ.

Nếu free không phải là NULL: khi một đối tượng mã bị hủy phân bổ, free sẽ được gọi trên dữ liệu không phải NULL được lưu trữ trong chỉ mục mới. Sử dụng Py_DecRef() khi lưu trữ PyObject.

Added in version 3.6: như _PyEval_RequestCodeExtraIndex

Thay đổi trong phiên bản 3.12: Đổi tên thành PyUnstable_Eval_RequestCodeExtraIndex. Tên riêng cũ không được dùng nữa nhưng sẽ có sẵn cho đến khi API thay đổi.

int PyUnstable_Code_GetExtra(PyObject *code, Py_ssize_t index, void **extra)
Đây là API không ổn định. Nó có thể thay đổi mà không có cảnh báo trong các bản phát hành nhỏ.

Đặt extra thành dữ liệu bổ sung được lưu trữ theo chỉ mục đã cho. Trả về 0 khi thành công. Đặt ngoại lệ và trả về -1 nếu thất bại.

Nếu không có dữ liệu nào được đặt trong chỉ mục, hãy đặt extra thành NULL và trả về 0 mà không đặt ngoại lệ.

Added in version 3.6: như _PyCode_GetExtra

Thay đổi trong phiên bản 3.12: Đổi tên thành PyUnstable_Code_GetExtra. Tên riêng cũ không được dùng nữa nhưng sẽ có sẵn cho đến khi API thay đổi.

int PyUnstable_Code_SetExtra(PyObject *code, Py_ssize_t index, void *extra)
Đây là API không ổn định. Nó có thể thay đổi mà không có cảnh báo trong các bản phát hành nhỏ.

Đặt dữ liệu bổ sung được lưu trữ theo chỉ mục đã cho thành extra. Trả về 0 khi thành công. Đặt ngoại lệ và trả về -1 nếu thất bại.

Added in version 3.6: như _PyCode_SetExtra

Thay đổi trong phiên bản 3.12: Đổi tên thành PyUnstable_Code_SetExtra. Tên riêng cũ không được dùng nữa nhưng sẽ có sẵn cho đến khi API thay đổi.