Làm cách nào để tắt các xác nhận trong Python?
Đó là, nếu một khẳng định không thành công, tôi không muốn nó ném đi AssertionError
, nhưng vẫn tiếp tục.
Làm thế nào để làm điều đó?
Câu trả lời:
Làm cách nào để tắt các xác nhận trong Python?
Có nhiều cách tiếp cận ảnh hưởng đến một quy trình, môi trường hoặc một dòng mã.
Tôi chứng minh từng điều.
Sử dụng -O
cờ (viết hoa O) vô hiệu hóa tất cả các câu lệnh khẳng định trong một quy trình.
Ví dụ:
$ python -Oc "assert False"
$ python -c "assert False"
Traceback (most recent call last):
File "<string>", line 1, in <module>
AssertionError
Lưu ý rằng bằng cách vô hiệu hóa, tôi có nghĩa là nó cũng không thực thi biểu thức theo sau nó:
$ python -Oc "assert 1/0"
$ python -c "assert 1/0"
Traceback (most recent call last):
File "<string>", line 1, in <module>
ZeroDivisionError: integer division or modulo by zero
Bạn cũng có thể sử dụng một biến môi trường để đặt cờ này.
Điều này sẽ ảnh hưởng đến mọi quy trình sử dụng hoặc kế thừa môi trường.
Ví dụ: trong Windows, thiết lập và sau đó xóa biến môi trường:
C:\>python -c "assert False"
Traceback (most recent call last):
File "<string>", line 1, in <module>
AssertionError
C:\>SET PYTHONOPTIMIZE=TRUE
C:\>python -c "assert False"
C:\>SET PYTHONOPTIMIZE=
C:\>python -c "assert False"
Traceback (most recent call last):
File "<string>", line 1, in <module>
AssertionError
Tương tự trong Unix (sử dụng set và unset cho chức năng tương ứng)
Bạn tiếp tục câu hỏi của mình:
nếu một xác nhận không thành công, tôi không muốn nó tạo ra một AssertionError, nhưng hãy tiếp tục.
Nếu bạn muốn mã không được thực thi, bạn có thể bắt hoặc đảm bảo luồng điều khiển không đạt đến xác nhận, ví dụ:
if False:
assert False, "we know this fails, but we don't get here"
hoặc bạn có thể gặp lỗi xác nhận:
try:
assert False, "this code runs, fails, and the exception is caught"
except AssertionError as e:
print(repr(e))
mà in:
AssertionError('this code runs, fails, and the exception is caught')
và bạn sẽ tiếp tục đi từ điểm bạn đã xử lý AssertionError
.
Từ các assert
tài liệu :
Một tuyên bố khẳng định như thế này:
assert expression #, optional_message
Tương đương với
if __debug__:
if not expression: raise AssertionError #(optional_message)
Và,
biến tích hợp
__debug__
làTrue
điều kiện bình thường,False
khi tối ưu hóa được yêu cầu (tùy chọn dòng lệnh-O
).
và xa hơn
Nhiệm vụ
__debug__
là bất hợp pháp. Giá trị cho biến tích hợp được xác định khi trình thông dịch khởi động.
Từ tài liệu sử dụng:
Bật tính năng tối ưu hóa cơ bản. Điều này thay đổi phần mở rộng tên tệp cho các tệp đã biên dịch (bytecode) từ .pyc thành .pyo. Xem thêm PYTHONOPTIMIZE.
và
Nếu điều này được đặt thành một chuỗi không rỗng, nó tương đương với việc chỉ định
-O
tùy chọn. Nếu được đặt thành số nguyên, nó tương đương với việc chỉ định-O
nhiều lần.
if False: assert False
) hoặc bạn có thể gặp lỗi Xác nhận. Đó là những lựa chọn của bạn. Đã cập nhật câu trả lời để giải quyết câu hỏi của bạn.
foo()
và khẳng định tắt: with skip_assertion(): foo()
. Lợi ích của việc này là rằng tôi không cần phải thêm lá cờ khác về chức năng
Assert
các đối tượng bằng Pass
các đối tượng). Một trình quản lý ngữ cảnh sẽ không trực tiếp làm việc đó, nhưng bạn có thể có một số loại cơ chế sử dụng các chức năng được trang trí theo cách đó. Bất kể, tôi không khuyên bạn nên nó. Tôi nghi ngờ lý do bạn muốn làm như vậy là bạn đang gọi mã mà bạn không kiểm soát và nhận được AssertionErrors. Nếu vậy, bạn có thể cần phải tìm một bản sửa lỗi khác.
Gọi Python bằng cờ -O:
test.py:
assert(False)
print 'Done'
Đầu ra:
C:\temp\py>C:\Python26\python.exe test.py
Traceback (most recent call last):
File "test.py", line 1, in <module>
assert(False)
AssertionError
C:\temp\py>C:\Python26\python.exe -O test.py
Done
Cả hai câu trả lời đã đưa ra đều hợp lệ (gọi Python bằng một trong hai -O
hoặc -OO
trên dòng lệnh).
Đây là sự khác biệt giữa chúng:
-O
Bật tính năng tối ưu hóa cơ bản. Điều này thay đổi phần mở rộng tên tệp cho các tệp đã biên dịch (bytecode) từ .pyc thành .pyo.
-OO
Docstrings Huỷ ngoài đến -O
tối ưu hóa.
(Từ tài liệu Python )
Sử dụng python -O
:
$ python -O
>>> assert False
>>>
Bạn KHÔNG nên vô hiệu hóa (hầu hết) các xác nhận. Họ mắc phải những lỗi không lường trước được khi sự chú ý ở nơi khác. Xem Quy tắc 5 trong "Sức mạnh của mười" .
Thay vào đó, hãy bảo vệ một số kiểm tra xác nhận đắt tiền bằng những thứ như:
import logging
logger = logging.getLogger(__name__)
if logger.getEffectiveLevel() < logging.DEBUG:
ok = check_expensive_property()
assert ok, 'Run !'
Một cách để giữ các xác nhận quan trọng và cho phép các assert
câu lệnh được tối ưu hóa là bằng cách nâng cao chúng trong một câu lệnh lựa chọn:
if foo_is_broken():
raise AssertionError('Foo is broken!')
__debug__
thành Sai nhưng điều đó không được phép.