Apa gunanya "menegaskan" dalam Python?

Jawaban:

1085

The assertpernyataan ada di hampir setiap bahasa pemrograman. Ini membantu mendeteksi masalah di awal program Anda, di mana penyebabnya jelas, daripada kemudian sebagai efek samping dari beberapa operasi lain.

Saat kamu melakukan...

assert condition

... Anda memberi tahu program untuk menguji kondisi itu, dan segera memicu kesalahan jika kondisinya salah.

Dalam Python, kira-kira sama dengan ini:

if not condition:
    raise AssertionError()

Cobalah di shell Python:

>>> assert True # nothing happens
>>> assert False
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError

Pernyataan dapat menyertakan pesan opsional, dan Anda dapat menonaktifkannya saat menjalankan juru bahasa.

Untuk mencetak pesan jika pernyataan gagal:

assert False, "Oh no! This assertion failed!"

Jangan tidak menggunakan kurung untuk memanggil assertseperti fungsi. Itu adalah pernyataan. Jika Anda melakukannya, assert(condition, message)Anda akan menjalankan assertdengan (condition, message)tuple sebagai parameter pertama.

Seperti untuk menonaktifkan mereka, saat menjalankan pythondalam mode dioptimalkan, di mana __debug__adalah False, pernyataan menegaskan akan diabaikan. Lewati saja -Obendera:

python -O script.py

Lihat di sini untuk dokumentasi yang relevan.

slezica
sumber
92
Nit: menegaskan adalah pernyataan dan bukan fungsi. Dan tidak seperti cetak , dalam Python 3 itu masih pernyataan .
Bob Stein
2
@Chaine menegaskan bahwa berarti "pastikan bahwa * sesuatu" Benar ". Jadi, tunjukkan == 3 akan memastikan bahwa a sama dengan 3; jika a tidak sama dengan 3 (yaitu a == 3 salah) maka ia akan meningkatkan kesalahan
Ant
5
Jika saya bisa menggunakan if not condition: raise AssertError(), mengapa saya harus menggunakan penegasan? Apakah ada kondisi di mana penegasan lebih baik daripada hanya menjadi bentuk if not conditionpernyataan yang lebih pendek ?
alpha_989
6
@ alpha_989 a) lebih pendek dan lebih mudah dibaca, b) Anda dapat menonaktifkan pernyataan tegas saat menjalankan interpreter (tidak demikian dengan manual if). Baca dokumen untuk info lebih lanjut :)
slezica
9
sama sekali tidak mengerti bagaimana jawaban ini mendapatkan begitu banyak suara, sebenarnya orang lain juga menjawab. pertanyaannya adalah "Apa gunanya" menegaskan "dengan Python?", jadi ia bertanya: kapan harus menggunakan, atau lebih tepatnya: apa skenario penggunaannya assert, tetapi setelah membaca semua jawaban, saya benar-benar tidak mendapatkan apa pun yang saya inginkan!
lnshi
424

Hati-hati dengan tanda kurung. Seperti yang telah ditunjukkan di atas, dalam Python 3, assertmasih merupakan pernyataan , jadi dengan analogi dengan print(..), seseorang dapat memperkirakan hal yang sama dengan assert(..)atau raise(..)tetapi Anda tidak seharusnya.

Ini penting karena:

assert(2 + 2 == 5, "Houston we've got a problem")

tidak akan bekerja, tidak seperti

assert 2 + 2 == 5, "Houston we've got a problem"

Alasan yang pertama tidak akan berfungsi adalah karena bool( (False, "Houston we've got a problem") )dievaluasi True.

Dalam pernyataan itu assert(False), ini hanya tanda kurung yang berlebihan False, yang mengevaluasi isinya. Tetapi dengan assert(False,)tanda kurung sekarang menjadi tuple, dan tuple non-kosong dievaluasi Truedalam konteks boolean.

Evgeni Sergeev
sumber
18
Saya datang ke sini mencari info persis tentang parens dan pesan follow. Terima kasih.
superbeck
6
Tapi assert (2 + 2 = 5), "Houston we've got a problem"harusnya ok, ya?
SherylHohman
4
@ SherylHohman, Anda juga dapat mencoba menjalankannya sendiri dan melihat apakah itu berfungsi atau tidak
DarkCygnus
2
Jangan lupa bahwa orang sering menggunakan tanda kurung untuk kelanjutan garis implisit PEP 8 yang sesuai prioritas operator).
cowbert
4
assert (2 + 2 = 5), "Houston we've got a problem"tidak akan bekerja ... tapi itu tidak ada hubungannya dengan pernyataan tegas, yang baik-baik saja. Kondisi Anda tidak akan berfungsi karena itu bukan suatu kondisi. Hilang sebentar =.
n1k31t4
133

Seperti yang dicatat oleh jawaban lain, assertmirip dengan melempar pengecualian jika kondisi yang diberikan tidak benar. Perbedaan penting adalah pernyataan tegas diabaikan jika Anda mengkompilasi kode Anda dengan opsi optimisasi -O. The dokumentasi mengatakan bahwa assert expressionlebih baik dapat digambarkan sebagai setara dengan

if __debug__:
   if not expression: raise AssertionError

Ini dapat berguna jika Anda ingin menguji kode Anda secara menyeluruh, kemudian merilis versi yang dioptimalkan ketika Anda senang bahwa tidak ada kasus pernyataan Anda gagal - ketika optimasi aktif, __debug__variabel menjadi False dan kondisi akan berhenti dievaluasi. Fitur ini juga dapat menangkap Anda jika Anda mengandalkan konfirmasi dan tidak menyadari bahwa mereka telah menghilang.

Neil Vass
sumber
Apakah ini berarti, bahwa jika variabel tertentu atau input yang benar (sesuai dengan kontrak dengan mana program ini ditulis) dapat mengakibatkan crash program, ketika dijalankan oleh pengguna (dengan asumsi bahwa -O flag digunakan ketika pengguna menjalankan program), Anda sebaiknya menggunakan if Not Error: raise Exception(“ this is a error”)? Dengan begitu, program masih akan menunjukkan sumber kesalahan, ketika pengguna menjalankannya ..
alpha_989
Di sisi lain, jika Anda berharap bahwa program bisa error karena logika yang salah / implementasi kode (tetapi bukan karena input yang sesuai dengan kontrak kepada pengguna program), Anda harus menggunakan assertpernyataan itu? Asumsinya di sini adalah bahwa ketika program dirilis ke pengguna akhir, Anda menggunakan flag -O, dengan demikian dengan asumsi bahwa semua bug telah dihapus. Karenanya, setiap kesalahan atau crash program disebabkan oleh input ke program yang valid sesuai kontrak, tetapi tidak dapat ditangani oleh program. Jadi harus memperingatkan pengguna seperti itu.
alpha_989
@ alpha_989 itu benar sekali. Saya suka menganggap pernyataan sebagai kewarasan memeriksa yang hanya untuk membantu Anda sebagai pengembang untuk memastikan bahwa apa yang Anda anggap benar benar benar saat Anda berkembang.
Christopher Shroba
52

Tujuan pernyataan Python adalah untuk memberi tahu pengembang tentang kesalahan yang tidak dapat dipulihkan dalam suatu program.

Pernyataan tidak dimaksudkan untuk memberi sinyal kondisi kesalahan yang diharapkan, seperti "file tidak ditemukan", di mana pengguna dapat mengambil tindakan korektif (atau coba lagi).

Cara lain untuk melihatnya adalah dengan mengatakan bahwa asersi adalah pemeriksaan diri internal dalam kode Anda. Mereka bekerja dengan menyatakan beberapa kondisi sebagai tidak mungkin dalam kode Anda. Jika kondisi ini tidak berlaku itu berarti ada bug dalam program.

Jika program Anda bebas bug, kondisi ini tidak akan pernah terjadi. Tetapi jika salah satu dari mereka benar- benar muncul, program akan macet dengan kesalahan pernyataan yang memberitahu Anda dengan tepat kondisi "mustahil" apa yang dipicu. Ini membuatnya lebih mudah untuk melacak dan memperbaiki bug di program Anda.

Berikut ringkasan dari tutorial tentang pernyataan Python yang saya tulis:

Pernyataan tegas Python adalah bantuan debugging, bukan mekanisme untuk menangani kesalahan run-time. Tujuan menggunakan pernyataan adalah untuk membiarkan pengembang menemukan akar penyebab bug lebih cepat. Kesalahan pernyataan tidak boleh dimunculkan kecuali ada bug di program Anda.

dbader
sumber
Terima kasih untuk artikelnya. Sangat membantu untuk memahami assertpernyataan dan kapan menggunakannya. Saya mencoba memahami sejumlah istilah yang Anda perkenalkan dalam artikel.
alpha_989
Saya pikir saya akan memposting komentar di sini sehingga lebih banyak orang akan mendapat manfaat dari klarifikasi. Maaf jika pertanyaannya terlalu naif.
alpha_989
Di blog Anda yang ditautkan, Anda memberikan contoh di mana Anda menyebutkan bahwa `tegaskan 0 <= harga <= produk ['harga']` benar, tetapi menggunakan `tegaskan user.is_admin (), 'Harus memiliki hak admin untuk menghapus '`dan assert store.product_exists(product_id), 'Unknown product id'ini bukan praktik yang baik, karena jika debug dimatikan maka userbahkan jika tidak adminakan dapat menghapus produk. Apakah Anda menganggapnya assert user.is_admin()sebagai unrecoverablekesalahan? Mengapa ini bukan self-check?
alpha_989
Jika Anda menganggap bahwa 'user.is_admin () `adalah input pengguna dan karenanya tidak boleh digunakan dalam assert statement, bukankah pricejuga dapat dianggap sebagai input pengguna? Mengapa Anda mempertimbangkan assert user.is_admin()validasi data tetapi tidak assert price?
alpha_989
1
@ LaryxDecidua Tidak, Anda bisa membacanya di situs web saya, tutorialnya tersedia untuk umum. Tekan saja escape atau klik simbol "x" kecil jika Anda tidak tertarik dengan buletin. Semoga ini bisa membantu :-)
dbader
51

Orang lain telah memberi Anda tautan ke dokumentasi.

Anda dapat mencoba yang berikut ini dalam shell interaktif:

>>> assert 5 > 2
>>> assert 2 > 5
Traceback (most recent call last):
  File "<string>", line 1, in <fragment>
builtins.AssertionError:

Pernyataan pertama tidak melakukan apa pun, sedangkan pernyataan kedua menimbulkan pengecualian. Ini adalah petunjuk pertama: menegaskan berguna untuk memeriksa kondisi yang seharusnya benar dalam posisi kode Anda (biasanya, awal (prasyarat) dan akhir fungsi (postkondisi)).

Pernyataan sebenarnya sangat terkait dengan pemrograman berdasarkan kontrak, yang merupakan praktik rekayasa yang sangat berguna:

http://en.wikipedia.org/wiki/Design_by_contract .

Baltasarq
sumber
Jadi apakah itu berarti kita dapat memeriksa kode dalam situasi seperti menegaskan (2> 5) dan meningkatkan kesalahan lain?
20
Lose the parens, menegaskan bukan fungsi.
pembuat pil
2
Kehilangan orangtua lebih penting daripada kelihatannya. Lihat di bawah .
Evgeni Sergeev
6
Sebenarnya menegaskan tanggal kembali (jauh sebelum "kontrak") ke Turing, ketika ia menulis salah satu makalah paling awal tentang bagaimana programmer dapat menangani tugas yang agak menakutkan untuk membuat program yang benar. Menemukan kertas itu dibiarkan sebagai latihan untuk pembaca, karena semua programmer dapat memperoleh manfaat dari menjadi terbiasa dengan karyanya. :-) turingarchive.org
Ron Burk
17

Dari dokumen:

Assert statements are a convenient way to insert debugging assertions into a program

Di sini Anda dapat membaca lebih lanjut: http://docs.python.org/release/2.5.2/ref/assert.html

gruszczy
sumber
Saya suka komentar ini karena hanya menjelaskan apa yang sangat jelas. pertanyaan saya adalah "jika saya telah menulis unit test yang tepat, mengapa saya perlu penegasan"? barang-barang itu tidak berjalan dalam produksi.
dtc
17

Pernyataan tegas memiliki dua bentuk.

Bentuk sederhana assert <expression>,, setara dengan

if __debug__:
    if not <expression>: raise AssertionError

Formulir diperpanjang assert <expression1>, <expression2>,, setara dengan

if __debug__:
    if not <expression1>: raise AssertionError, <expression2>
Bohdan
sumber
16

Pernyataan adalah cara sistematis untuk memeriksa bahwa keadaan internal suatu program adalah seperti yang diharapkan oleh programmer, dengan tujuan menangkap bug. Lihat contoh di bawah ini.

>>> number = input('Enter a positive number:')
Enter a positive number:-1
>>> assert (number > 0), 'Only positive numbers are allowed!'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError: Only positive numbers are allowed!
>>> 
Yakub Abraham
sumber
1
Juga, pernyataan dapat sering digunakan dalam program pengujian unit. stackoverflow.com/questions/1383/what-is-unit-testing
panofish
7

Ini adalah contoh sederhana, simpan dalam file ini (misalkan b.py)

def chkassert(num):
    assert type(num) == int


chkassert('a')

dan hasilnya kapan $python b.py

Traceback (most recent call last):
  File "b.py", line 5, in <module>
    chkassert('a')
  File "b.py", line 2, in chkassert
    assert type(num) == int
AssertionError
Gaurav Agarwal
sumber
6

jika pernyataan setelah pernyataan benar maka program berlanjut, tetapi jika pernyataan setelah pernyataan salah maka program memberikan kesalahan. Sederhana seperti itu.

misalnya:

assert 1>0   #normal execution
assert 0>1   #Traceback (most recent call last):
             #File "<pyshell#11>", line 1, in <module>
             #assert 0>1
             #AssertionError
abe312
sumber
4

The assertpernyataan ada di hampir setiap bahasa pemrograman. Ini membantu mendeteksi masalah di awal program Anda, di mana penyebabnya jelas, daripada kemudian sebagai efek samping dari beberapa operasi lain. Mereka selalu mengharapkan suatu Truekondisi.

Ketika Anda melakukan sesuatu seperti:

assert condition

Anda memberi tahu program untuk menguji kondisi itu dan segera memicu kesalahan jika salah.

Dalam Python, assertekspresi , setara dengan:

if __debug__:
    if not <expression>: raise AssertionError

Anda dapat menggunakan ekspresi yang diperluas untuk menyampaikan pesan opsional :

if __debug__:
    if not (expression_1): raise AssertionError(expression_2)

Cobalah di juru bahasa Python:

>>> assert True # Nothing happens because the condition returns a True value.
>>> assert False # A traceback is triggered because this evaluation did not yield an expected value.
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError

Ada beberapa peringatan untuk dilihat sebelum menggunakannya terutama bagi mereka yang menganggap beralih di antara pernyataan assertdan if. Tujuan untuk digunakan assertadalah pada saat-saat ketika program memverifikasi suatu kondisi dan mengembalikan nilai yang harus menghentikan program segera daripada mengambil beberapa cara alternatif untuk mem-bypass kesalahan:

1. Tanda kurung

Seperti yang mungkin Anda perhatikan, assertpernyataan itu menggunakan dua kondisi. Oleh karena itu, jangan tidak menggunakan tanda kurung untuk englobe mereka sebagai salah satu nasihat yang jelas. Jika Anda melakukan seperti:

assert (condition, message)

Contoh:

>>> assert (1==2, 1==1)
<stdin>:1: SyntaxWarning: assertion is always true, perhaps remove parentheses?

Anda akan menjalankan assertdengan (condition, message)yang mewakili tuple sebagai parameter pertama, dan ini terjadi karena tuple tidak kosong di Python selaluTrue . Namun, Anda dapat melakukan secara terpisah tanpa masalah:

assert (condition), "message"

Contoh:

>>> assert (1==2), ("This condition returns a %s value.") % "False"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError: This condition returns a False value.

2. Tujuan debug

Jika Anda bertanya-tanya tentang kapan menggunakan assertpernyataan. Ambil contoh yang digunakan dalam kehidupan nyata:

* Ketika program Anda cenderung mengontrol setiap parameter yang dimasukkan oleh pengguna atau apa pun yang lain:

def loremipsum(**kwargs):
    kwargs.pop('bar') # return 0 if "bar" isn't in parameter
    kwargs.setdefault('foo', type(self)) # returns `type(self)` value by default
    assert (len(kwargs) == 0), "unrecognized parameter passed in %s" % ', '.join(kwargs.keys())

* Kasus lain adalah pada matematika ketika 0 atau non-positif sebagai koefisien atau konstan pada persamaan tertentu:

def discount(item, percent):
    price = int(item['price'] * (1.0 - percent))
    print(price)
    assert (0 <= price <= item['price']),\
            "Discounted prices cannot be lower than 0 "\
            "and they cannot be higher than the original price."

    return price

* atau bahkan contoh sederhana dari implementasi boolean:

def true(a, b):
    assert (a == b), "False"
    return 1

def false(a, b):
    assert (a != b), "True"
    return 0

3. Pemrosesan data atau validasi data

Yang paling penting adalah untuk tidak bergantung pada assertpernyataan untuk menjalankan pemrosesan data atau validasi data karena pernyataan ini dapat dimatikan pada inisialisasi Python dengan -Oatau -OOflag - artinya nilai 1, 2, dan 0 (sebagai default), masing-masing - atau PYTHONOPTIMIZEvariabel lingkungan .

Nilai 1:

* menegaskan dinonaktifkan;

* file bytecode dihasilkan menggunakan .pyoekstensi alih-alih .pyc;

* sys.flags.optimizediatur ke 1 ( True);

* dan, __debug__diatur ke False;

Nilai 2: menonaktifkan satu hal lagi

* docstring dinonaktifkan;

Oleh karena itu, menggunakan assertpernyataan untuk memvalidasi jenis data yang diharapkan sangat berbahaya, menyiratkan bahkan untuk beberapa masalah keamanan. Kemudian, jika Anda perlu memvalidasi beberapa izin saya sarankan Anda raise AuthErrorsebagai gantinya. Sebagai prasyarat efektif, suatu assertumumnya digunakan oleh pemrogram di perpustakaan atau modul yang tidak memiliki pengguna berinteraksi secara langsung.

pembunuh
sumber
3

Seperti yang dirangkum secara ringkas di C2 Wiki :

Pernyataan adalah ekspresi boolean pada titik tertentu dalam suatu program yang akan benar kecuali ada bug dalam program.

Anda dapat menggunakan assertpernyataan untuk mendokumentasikan pemahaman Anda tentang kode pada titik program tertentu. Misalnya, Anda dapat mendokumentasikan asumsi atau jaminan tentang input (prakondisi), status program (invarian), atau output (postkondisi).

Jika pernyataan Anda pernah gagal, ini merupakan peringatan bagi Anda (atau penerus Anda) bahwa pemahaman Anda tentang program itu salah ketika Anda menulisnya, dan itu kemungkinan mengandung bug.

Untuk informasi lebih lanjut, John Regehr memiliki posting blog yang bagus tentang Penggunaan Pernyataan , yang juga berlaku untuk assertpernyataan Python .

avandeursen
sumber
2

Jika Anda pernah ingin tahu persis apa fungsi cadangan tidak digunakan dalam python, ketikkan help(enter_keyword)

Pastikan jika Anda memasukkan kata kunci khusus yang Anda masukkan sebagai string.

ytpillai
sumber
2

Python assert pada dasarnya adalah bantuan debugging yang menguji kondisi untuk memeriksa sendiri internal kode Anda. Penegasan membuat proses debug sangat mudah ketika kode Anda masuk ke kasus tepi yang mustahil. Tegaskan memeriksa kasus-kasus mustahil.

Katakanlah ada fungsi untuk menghitung harga barang setelah diskon:

def calculate_discount(price, discount):
    discounted_price = price - [discount*price]
    assert 0 <= discounted_price <= price
    return discounted_price

di sini, discounted_price tidak boleh kurang dari 0 dan lebih besar dari harga sebenarnya. Jadi, jika kondisi di atas dilanggar, maka akan muncul Kesalahan Pernyataan, yang membantu pengembang untuk mengidentifikasi bahwa sesuatu yang mustahil telah terjadi.

Semoga bermanfaat :)

Nitish Chauhan
sumber
2
assertberguna dalam konteks debugging, tetapi tidak boleh diandalkan di luar konteks debugging.
FluxIX
2

Penjelasan singkat saya adalah:

  • assertmemunculkan AssertionErrorjika ekspresi salah, jika tidak hanya melanjutkan kode, dan jika ada koma apa pun itu AssertionError: whatever after comma, dan untuk kode seperti:raise AssertionError(whatever after comma)

Tutorial terkait tentang ini:

https://www.tutorialspoint.com/python/assertions_in_python.htm

U10-Maju
sumber
Jawabannya menyediakan cara menggunakan assert, tetapi tidak kapan menggunakan (atau tidak menggunakan) suatu assert; juga mencatat bahwa assertdapat dinonaktifkan jika __debug__yaitu Falseakan berguna.
FluxIX
1

Di Pycharm, jika Anda menggunakan assertbersama isinstanceuntuk mendeklarasikan jenis objek, ia akan memungkinkan Anda mengakses metode dan atribut dari objek induk saat Anda mengode, itu akan secara otomatis dilengkapi.

Sebagai contoh, katakanlah self.object1.object2adalah MyClassobjek.

import MyClasss

def code_it(self):
    testObject = self.object1.object2 # at this point, program doesn't know that testObject  is a MyClass object yet
    assert isinstance(testObject , MyClasss) # now the program knows testObject is a MyClass object
    testObject.do_it() # from this point on, PyCharm will be able to auto-complete when you are working on testObject
alwbtc
sumber
0

Seperti yang ditulis dalam jawaban lain, assertpernyataan digunakan untuk memeriksa keadaan program pada titik tertentu.

Saya tidak akan mengulangi apa yang dikatakan tentang pesan terkait, tanda kurung, atau -Oopsi dan __debug__konstan. Periksa juga dokumen untuk informasi tangan pertama. Saya akan fokus pada pertanyaan Anda: apa gunanya assert? Lebih tepatnya, kapan (dan kapan tidak) harus digunakan assert?

The assertpernyataan berguna untuk debug program, tetapi berkecil untuk memeriksa input pengguna. Saya menggunakan aturan praktis berikut: menjaga pernyataan untuk mendeteksi situasi yang seharusnya tidak terjadi . Input pengguna mungkin salah, mis. Kata sandi terlalu pendek, tetapi ini bukan hal yang seharusnya tidak terjadi . Jika diameter lingkaran tidak dua kali lebih besar dari jari-jarinya, Anda berada dalam kasus ini seharusnya tidak terjadi .

Yang paling menarik, dalam pikiran saya, penggunaan assertterinspirasi oleh pemrograman dengan kontrak seperti yang dijelaskan oleh B. Meyer dalam [Konstruksi Perangkat Lunak Berorientasi Objek] ( https://www.eiffel.org/doc/eiffel/Object-Oriented_Software_Construction%) 2C_2nd_Edition ) dan diimplementasikan dalam [Bahasa pemrograman Eiffel] ( https://en.wikipedia.org/wiki/Eiffel_(programming_language) ). Anda tidak dapat sepenuhnya meniru pemrograman dengan kontrak menggunakan assertpernyataan itu, tetapi menarik untuk mempertahankan maksudnya.

Ini sebuah contoh. Bayangkan Anda harus menulis headfungsi (seperti [ headfungsi di Haskell] ( http://www.zvon.org/other/haskell/Outputprelude/head_f.html )). Spesifikasi yang Anda berikan adalah: "jika daftar tidak kosong, kembalikan item pertama dari daftar". Lihatlah implementasi berikut:

>>> def head1(xs): return xs[0]

Dan

>>> def head2(xs):
...     if len(xs) > 0:
...         return xs[0]
...     else:
...         return None

(Ya, ini bisa ditulis sebagai return xs[0] if xs else None, tapi bukan itu intinya) .

Jika daftar ini tidak kosong, kedua fungsi memiliki hasil yang sama dan hasil ini benar:

>>> head1([1, 2, 3]) == head2([1, 2, 3]) == 1
True

Oleh karena itu, kedua implementasi itu (saya harap) benar. Mereka berbeda ketika Anda mencoba untuk mengambil item kepala dari daftar kosong:

>>> head1([])
Traceback (most recent call last):
...
IndexError: list index out of range

Tapi:

>>> head2([]) is None
True

Sekali lagi, kedua implementasi sudah benar, karena tidak ada yang harus memberikan daftar kosong ke fungsi-fungsi ini (kami di luar spesifikasi ). Itu panggilan yang salah, tetapi jika Anda melakukan panggilan seperti itu, apa pun bisa terjadi. Satu fungsi memunculkan eksepsi, yang lain mengembalikan nilai khusus. Yang paling penting adalah: kita tidak bisa mengandalkan perilaku ini . Jika xskosong, ini akan berfungsi:

print(head2(xs))

Tetapi ini akan membuat crash program:

print(head1(xs))

Untuk menghindari beberapa kejutan, saya ingin tahu kapan saya menyampaikan beberapa argumen yang tidak terduga ke suatu fungsi. Dengan kata lain: Saya ingin tahu kapan perilaku yang diamati tidak dapat diandalkan, karena itu tergantung pada implementasinya, bukan pada spesifikasinya. Tentu saja, saya dapat membaca spesifikasinya, tetapi programmer tidak selalu membaca dengan seksama dokumen.

Bayangkan jika saya memiliki cara untuk memasukkan spesifikasi ke dalam kode untuk mendapatkan efek berikut: ketika saya melanggar spesifikasi, misalnya dengan meneruskan daftar kosong head, saya mendapat peringatan. Itu akan sangat membantu untuk menulis program yang benar (yaitu sesuai dengan spesifikasi). Dan di situlah assert memasuki adegan:

>>> def head1(xs):
...     assert len(xs) > 0, "The list must not be empty"
...     return xs[0]

Dan

>>> def head2(xs):
...     assert len(xs) > 0, "The list must not be empty"
...     if len(xs) > 0:
...         return xs[0]
...     else:
...         return None

Sekarang kita punya:

>>> head1([])
Traceback (most recent call last):
...
AssertionError: The list must not be empty

Dan:

>>> head2([])
Traceback (most recent call last):
...
AssertionError: The list must not be empty

Perhatikan bahwa head1melempar AssertionError, bukan IndexError. Itu penting karena merupakan AssertionErrortidak setiap kesalahan runtime: itu sinyal pelanggaran spesifikasi. Saya ingin peringatan, tetapi saya mendapatkan kesalahan. Untungnya, saya dapat menonaktifkan cek (menggunakan -Oopsi), tetapi dengan risiko saya sendiri. Saya akan melakukannya crash sangat mahal, dan berharap yang terbaik. Bayangkan program saya tertanam dalam pesawat ruang angkasa yang bergerak melalui lubang hitam. Saya akan menonaktifkan pernyataan dan berharap program ini cukup kuat untuk tidak crash selama mungkin.

Contoh ini hanya tentang prasyarat, bisa Anda gunakan assertuntuk memeriksa postconditions (nilai pengembalian dan / atau negara) dan invarian (keadaan kelas). Perhatikan bahwa memeriksa kondisi pos dan invarian dengan assertbisa rumit:

  • untuk postconditions, Anda perlu menetapkan nilai kembali ke variabel, dan mungkin untuk menyimpan keadaan awal objek jika Anda berurusan dengan metode;
  • untuk invarian, Anda harus memeriksa keadaan sebelum dan sesudah pemanggilan metode.

Anda tidak akan memiliki sesuatu yang secanggih Eiffel, tetapi Anda dapat meningkatkan kualitas keseluruhan program.


Untuk meringkas, assertpernyataan itu adalah cara mudah untuk mendeteksi situasi yang seharusnya tidak terjadi . Pelanggaran terhadap spesifikasi (mis. Meneruskan daftar kosong ke head) adalah kelas utama ini seharusnya tidak terjadi situasi. Oleh karena itu, sementara assertpernyataan dapat digunakan untuk mendeteksi situasi yang tidak terduga, itu adalah cara istimewa untuk memastikan bahwa spesifikasi terpenuhi. Setelah Anda memasukkan assertpernyataan ke dalam kode untuk mewakili spesifikasi, kami dapat berharap Anda telah meningkatkan kualitas program karena argumen yang salah, nilai pengembalian yang salah, keadaan kelas yang salah ..., akan dilaporkan.

jferard
sumber
-2

format: menegaskan Ekspresi [, argumen] Ketika menegaskan menemukan pernyataan, Python mengevaluasi ekspresi. Jika pernyataan itu tidak benar, pengecualian dimunculkan (assertionError). Jika pernyataan gagal, Python menggunakan ArgumentExpression sebagai argumen untuk AssertionError. Pengecualian AssertionError dapat ditangkap dan ditangani seperti pengecualian lain menggunakan pernyataan coba-kecuali, tetapi jika tidak ditangani, mereka akan menghentikan program dan menghasilkan traceback. Contoh:

def KelvinToFahrenheit(Temperature):    
    assert (Temperature >= 0),"Colder than absolute zero!"    
    return ((Temperature-273)*1.8)+32    
print KelvinToFahrenheit(273)    
print int(KelvinToFahrenheit(505.78))    
print KelvinToFahrenheit(-5)    

Ketika kode di atas dieksekusi, ia menghasilkan hasil sebagai berikut:

32.0
451
Traceback (most recent call last):    
  File "test.py", line 9, in <module>    
    print KelvinToFahrenheit(-5)    
  File "test.py", line 4, in KelvinToFahrenheit    
    assert (Temperature >= 0),"Colder than absolute zero!"    
AssertionError: Colder than absolute zero!    
Bhavya Joshi
sumber
-2
def getUser(self, id, Email):

    user_key = id and id or Email

    assert user_key

Dapat digunakan untuk memastikan parameter dilewatkan dalam panggilan fungsi.

pengguna2725012
sumber
1
Ini akan berhasil, tetapi dari apa yang saya pahami, menegaskan tidak boleh digunakan untuk memeriksa input pengguna, karena mereka dapat dimatikan saat run-time. Jika Anda benar-benar ingin menegakkan atau memvalidasi input pengguna, gunakan if not user_key: raise ValueError()Periksa 2 paragraf terakhir di sini: wiki.python.org/moin/UsingAssertionsEffectively
alpha_989
asserttidak boleh digunakan untuk validasi input karena validasi akan dihapus jika __debug__ada False. Juga menggunakan pernyataan untuk tujuan non-debug dapat menyebabkan orang untuk menangkap hasil AssertionError, yang dapat membuat debug lebih sulit daripada lebih sedikit.
FluxIX
-4
>>>this_is_very_complex_function_result = 9
>>>c = this_is_very_complex_function_result
>>>test_us = (c < 4)

>>> #first we try without assert
>>>if test_us == True:
    print("YES! I am right!")
else:
    print("I am Wrong, but the program still RUNS!")

I am Wrong, but the program still RUNS!


>>> #now we try with assert
>>> assert test_us
Traceback (most recent call last):
  File "<pyshell#52>", line 1, in <module>
    assert test_us
AssertionError
>>> 
rianhariadi.com
sumber
-4

Pada dasarnya makna kata kunci yang menegaskan adalah bahwa jika kondisi tidak benar maka melalui assertionerror lain itu melanjutkan misalnya dalam python.

kode-1

a=5

b=6

assert a==b

KELUARAN:

assert a==b

AssertionError

kode-2

a=5

b=5

assert a==b

KELUARAN:

Process finished with exit code 0
ujjwal_bansal
sumber
2
tolong format kode Anda dengan benar. juga, bagaimana hal ini meningkatkan jawaban sebelumnya?
c2huc2hu
apakah ada masalah dalam penjelasan saya?
ujjwal_bansal
penjelasan Anda tidak menambahkan apa pun pada jawaban yang ada, dan tata bahasa yang buruk membuatnya sulit dibaca. jika Anda mencari pertanyaan untuk dijawab, coba jelajahi umpan pertanyaan baru.
c2huc2hu
Jawaban yang diberikan tidak menjawab cara menggunakan assert, tetapi tidak menjawab kapan harus menggunakan (atau tidak menggunakan) suatu assert.
FluxIX