Chế độ phát triển Python¶
Added in version 3.7.
Chế độ phát triển Python giới thiệu các kiểm tra thời gian chạy bổ sung quá đắt để được bật theo mặc định. Nó không được dài dòng hơn mặc định nếu mã đúng; cảnh báo mới chỉ được đưa ra khi phát hiện thấy sự cố.
Nó có thể được kích hoạt bằng tùy chọn dòng lệnh -X dev hoặc bằng cách đặt biến môi trường PYTHONDEVMODE thành 1.
Xem thêm Python debug build.
Tác dụng của Chế độ phát triển Python¶
Việc bật Chế độ phát triển Python tương tự như lệnh sau, nhưng có thêm các hiệu ứng được mô tả bên dưới:
PYTHONMALLOC=gỡ lỗi PYTHONASYNCIODEBUG=1 python -W mặc định -X lỗi xử lý
Tác dụng của Chế độ phát triển Python:
Thêm
defaultwarning filter. Các cảnh báo sau đây được hiển thị:Thông thường, các cảnh báo trên được lọc theo warning filters mặc định.
Nó hoạt động như thể tùy chọn dòng lệnh
-W defaultđược sử dụng.Sử dụng tùy chọn dòng lệnh
-W errorhoặc đặt biến môi trườngPYTHONWARNINGSthànherrorđể coi cảnh báo là lỗi.Cài đặt móc gỡ lỗi trên bộ cấp phát bộ nhớ để kiểm tra:
Tràn bộ đệm
Tràn bộ đệm
Vi phạm cấp phát bộ nhớ API
Sử dụng GIL không an toàn
Xem chức năng
PyMem_SetupDebugHooks()C.Nó hoạt động như thể biến môi trường
PYTHONMALLOCđược đặt thànhdebug.Để bật Chế độ phát triển Python mà không cần cài đặt móc gỡ lỗi trên bộ cấp phát bộ nhớ, hãy đặt biến môi trường
PYTHONMALLOCthànhdefault.Gọi
faulthandler.enable()khi khởi động Python để cài đặt trình xử lý cho các tín hiệuSIGSEGV,SIGFPE,SIGABRT,SIGBUSvàSIGILLnhằm kết xuất truy nguyên Python khi gặp sự cố.Nó hoạt động như thể tùy chọn dòng lệnh
-X faulthandlerđược sử dụng hoặc nếu biến môi trườngPYTHONFAULTHANDLERđược đặt thành1.Kích hoạt asyncio debug mode. Ví dụ:
asynciokiểm tra các coroutine không được chờ đợi và ghi lại chúng.Nó hoạt động như thể biến môi trường
PYTHONASYNCIODEBUGđược đặt thành1.Kiểm tra các đối số encoding và errors để biết các hoạt động mã hóa và giải mã chuỗi. Ví dụ:
open(),str.encode()vàbytes.decode().Theo mặc định, để có hiệu suất tốt nhất, đối số errors chỉ được kiểm tra ở lỗi mã hóa/giải mã đầu tiên và đối số encoding đôi khi bị bỏ qua đối với các chuỗi trống.
Hàm hủy
io.IOBaseghi lại các ngoại lệclose().
Chế độ phát triển Python không bật mô-đun tracemalloc theo mặc định vì chi phí chung (đối với hiệu suất và bộ nhớ) sẽ quá lớn. Việc kích hoạt mô-đun tracemalloc sẽ cung cấp thêm thông tin về nguồn gốc của một số lỗi. Ví dụ: ResourceWarning ghi lại dấu vết nơi tài nguyên được phân bổ và lỗi tràn bộ đệm sẽ ghi lại dấu vết nơi khối bộ nhớ được phân bổ.
Chế độ phát triển Python không ngăn tùy chọn dòng lệnh -O xóa các câu lệnh assert cũng như cài đặt __debug__ thành False.
Chế độ phát triển Python chỉ có thể được bật khi khởi động Python. Giá trị của nó có thể được đọc từ sys.flags.dev_mode.
Thay đổi trong phiên bản 3.8: Hàm hủy io.IOBase hiện ghi lại các ngoại lệ close().
Thay đổi trong phiên bản 3.9: Các đối số encoding và errors hiện đã được kiểm tra cho các hoạt động mã hóa và giải mã chuỗi.
Ví dụ về cảnh báo tài nguyên¶
Ví dụ về tập lệnh đếm số dòng của tệp văn bản được chỉ định trong dòng lệnh
hệ thống nhập khẩu
chắc chắn chính():
fp = open(sys.argv[1])
nlines = len(fp.readlines())
in(nlines)
Tệp # The bị đóng hoàn toàn
nếu __name__ == "__main__":
chính()
Tập lệnh không đóng tệp một cách rõ ràng. Theo mặc định, Python không đưa ra bất kỳ cảnh báo nào. Ví dụ sử dụng README.txt, có 269 dòng:
$ python script.py README.txt
269
Việc bật Chế độ phát triển Python sẽ hiển thị cảnh báo ResourceWarning:
$ python -X dev script.py README.txt
269
script.py:10: ResourceWarning: tệp không được tiết lộ <_io.TextIOWrapper name='README.rst' mode='r' mã hóa='UTF-8'>
chính()
ResourceWarning: Kích hoạt tracemalloc để lấy lại dấu vết phân bổ đối tượng
Ngoài ra, việc bật tracemalloc sẽ hiển thị dòng nơi tệp được mở:
$ python -X dev -X tracemalloc=5 script.py README.rst
269
script.py:10: ResourceWarning: tệp không được tiết lộ <_io.TextIOWrapper name='README.rst' mode='r' mã hóa='UTF-8'>
chính()
Đối tượng được phân bổ tại (cuộc gọi gần đây nhất gần đây nhất):
Tệp "script.py", lineno 10
chính()
Tệp "script.py", lineno 4
fp = open(sys.argv[1])
Cách khắc phục là đóng tệp một cách rõ ràng. Ví dụ sử dụng trình quản lý bối cảnh
chắc chắn chính():
# Close tệp một cách rõ ràng khi thoát khỏi khối with
với open(sys.argv[1]) là fp:
nlines = len(fp.readlines())
in(nlines)
Việc không đóng tài nguyên một cách rõ ràng có thể khiến tài nguyên mở lâu hơn dự kiến; nó có thể gây ra sự cố nghiêm trọng khi thoát Python. Nó rất tệ ở CPython, nhưng nó thậm chí còn tệ hơn ở PyPy. Việc đóng tài nguyên một cách rõ ràng làm cho ứng dụng trở nên xác định hơn và đáng tin cậy hơn.
Ví dụ về lỗi mô tả tệp không hợp lệ¶
Tập lệnh hiển thị dòng đầu tiên của chính nó
hệ điều hành nhập khẩu
chắc chắn chính():
fp = mở(__file__)
dòng đầu tiên = fp.readline()
print(firstline.rstrip())
os.close(fp.fileno())
Tệp # The bị đóng hoàn toàn
chính()
Theo mặc định, Python không đưa ra bất kỳ cảnh báo nào:
$ python script.py
hệ điều hành nhập khẩu
Chế độ phát triển Python hiển thị ResourceWarning và ghi lại lỗi "Bộ mô tả tệp xấu" khi hoàn thiện đối tượng tệp:
$ python -X dev script.py
hệ điều hành nhập khẩu
script.py:10: ResourceWarning: tệp không được tiết lộ <_io.TextIOWrapper name='script.py' mode='r' Encoding='UTF-8'>
chính()
ResourceWarning: Kích hoạt tracemalloc để lấy lại dấu vết phân bổ đối tượng
Ngoại lệ bị bỏ qua trong: <_io.TextIOWrapper name='script.py' mode='r' Encoding='UTF-8'>
Traceback (cuộc gọi gần đây nhất):
Tệp "script.py", dòng 10, trong <module>
chính()
OSError: [Errno 9] Bộ mô tả tệp không hợp lệ
os.close(fp.fileno()) đóng bộ mô tả tập tin. Khi trình hoàn thiện đối tượng tệp cố gắng đóng lại bộ mô tả tệp, nó không thành công với lỗi Bad file descriptor. Bộ mô tả tập tin chỉ được đóng một lần. Trong trường hợp xấu nhất, việc đóng nó hai lần có thể dẫn đến sự cố (xem ví dụ về bpo-18748).
Cách khắc phục là xóa dòng os.close(fp.fileno()) hoặc mở file bằng closefd=False.