Bagaimana cara menonaktifkan pernyataan dengan Python?
Artinya, jika suatu pernyataan gagal, saya tidak ingin ia melempar AssertionError
, tetapi terus berjalan.
Bagaimana aku melakukan itu?
Jawaban:
Bagaimana cara menonaktifkan pernyataan dengan Python?
Ada beberapa pendekatan yang memengaruhi satu proses, lingkungan, atau satu baris kode.
Saya mendemonstrasikan masing-masing.
Menggunakan -O
bendera (kapital O) menonaktifkan semua pernyataan assert dalam suatu proses.
Sebagai contoh:
$ python -Oc "assert False"
$ python -c "assert False"
Traceback (most recent call last):
File "<string>", line 1, in <module>
AssertionError
Perhatikan bahwa dengan menonaktifkan maksud saya itu juga tidak mengeksekusi ekspresi yang mengikutinya:
$ 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
Anda juga dapat menggunakan variabel lingkungan untuk menyetel tanda ini.
Ini akan mempengaruhi setiap proses yang menggunakan atau mewarisi lingkungan.
Misalnya, di Windows, mengatur dan menghapus variabel lingkungan:
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
Sama di Unix (menggunakan set dan unset untuk fungsionalitas masing-masing)
Anda melanjutkan pertanyaan Anda:
jika sebuah pernyataan gagal, saya tidak ingin ia menampilkan AssertionError, tetapi untuk melanjutkan.
Jika Anda ingin kode yang gagal dijalankan, Anda dapat memastikan aliran kontrol tidak mencapai pernyataan, misalnya:
if False:
assert False, "we know this fails, but we don't get here"
atau Anda dapat menangkap kesalahan pernyataan:
try:
assert False, "this code runs, fails, and the exception is caught"
except AssertionError as e:
print(repr(e))
yang mencetak:
AssertionError('this code runs, fails, and the exception is caught')
dan Anda akan terus melanjutkan dari titik Anda menangani AssertionError
.
Dari yang assert
dokumentasi :
Pernyataan tegas seperti ini:
assert expression #, optional_message
Setara dengan
if __debug__:
if not expression: raise AssertionError #(optional_message)
Dan,
variabel built-in
__debug__
adalahTrue
dalam keadaan normal,False
ketika optimasi diminta (perintah baris opsi-O
).
dan selanjutnya
Tugas ke
__debug__
ilegal. Nilai untuk variabel built-in ditentukan saat interpreter dimulai.
Dari dokumen penggunaan:
Aktifkan pengoptimalan dasar. Ini mengubah ekstensi nama file untuk file yang dikompilasi (bytecode) dari .pyc menjadi .pyo. Lihat juga PITONOPTIMASI.
dan
Jika ini disetel ke string tidak kosong, ini setara dengan menentukan
-O
opsi. Jika disetel ke bilangan bulat, ini setara dengan menetapkan-O
beberapa kali.
if False: assert False
) atau Anda dapat menangkap kesalahan Penegasan. Itu adalah pilihanmu. Memperbarui jawaban untuk menjawab pertanyaan Anda.
foo()
dan pernyataan mematikan: with skip_assertion(): foo()
. Manfaat dari ini adalah bahwa saya tidak perlu menambahkan bendera lain pada fungsinya
Assert
objek dengan Pass
objek). Manajer konteks tidak akan langsung bekerja untuk itu, tetapi Anda dapat memiliki semacam mekanisme yang menggunakan fungsi dekorasi dengan cara itu. Terlepas dari itu, saya tidak merekomendasikannya. Saya curiga alasan Anda ingin melakukannya adalah karena Anda memanggil kode yang tidak Anda kendalikan dan mendapatkan AssertionErrors. Jika demikian, Anda mungkin perlu mencari perbaikan lain.
Panggil Python dengan tanda -O:
test.py:
assert(False)
print 'Done'
Keluaran:
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
Kedua jawaban yang sudah diberikan adalah valid (panggil Python dengan salah satu -O
atau -OO
pada baris perintah).
Inilah perbedaan di antara keduanya:
-O
Aktifkan pengoptimalan dasar. Ini mengubah ekstensi nama file untuk file yang dikompilasi (bytecode) dari .pyc menjadi .pyo.
-OO
Buang dokumen selain-O
pengoptimalan.
(Dari dokumentasi Python )
Penggunaan python -O
:
$ python -O
>>> assert False
>>>
Anda TIDAK boleh menonaktifkan (sebagian besar) pernyataan. Mereka menangkap kesalahan yang tidak terduga saat perhatian ada di tempat lain. Lihat Aturan 5 dalam "Kekuatan sepuluh" .
Sebaliknya, lindungi beberapa pemeriksaan pernyataan yang mahal dengan sesuatu seperti:
import logging
logger = logging.getLogger(__name__)
if logger.getEffectiveLevel() < logging.DEBUG:
ok = check_expensive_property()
assert ok, 'Run !'
Salah satu cara untuk mempertahankan pernyataan penting, dan memungkinkan assert
pernyataan dioptimalkan adalah dengan memunculkan pernyataan pemilihan:
if foo_is_broken():
raise AssertionError('Foo is broken!')
__debug__
ke False tetapi itu tidak diizinkan.