Python'da “assert” kullanımı nedir?


Yanıtlar:


1082

Bu assertifade neredeyse her programlama dilinde mevcuttur. Daha sonra başka bir işlemin yan etkisi olarak değil, sorunun açık olduğu programınızın başlangıcındaki sorunları algılamaya yardımcı olur.

Bunu yaptığınızda ...

assert condition

... programa bu koşulu test etmesini söylüyorsunuz ve koşul yanlışsa derhal bir hata tetikliyorsunuz.

Python'da kabaca buna eşittir:

if not condition:
    raise AssertionError()

Python kabuğunda deneyin:

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

Onaylar isteğe bağlı bir mesaj içerebilir ve yorumlayıcıyı çalıştırırken bunları devre dışı bırakabilirsiniz.

Onaylama başarısız olursa bir mesajı yazdırmak için:

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

Do not çağırmak için parantez kullanmak assertbir işlev gibi. Bu bir ifadedir. Bunu yaparsanız , ilk parametre olarak bir tuple ile assert(condition, message)çalışacaksınız .assert(condition, message)

Çalıştırırken, onları devre dışı bırakmayı gelince pythonoptimize modunda __debug__ise False, assert ifadeleri dikkate alınmaz. Sadece -Obayrağı geç:

python -O script.py

İlgili belgeler için buraya bakın .


92
Nit: assert bir işlev değil, bir ifadedir. Ve baskıdan farklı olarak , Python 3'te hala bir ifade .
Bob Stein

2
@Chaine assert, "* bir şeyin" doğru olduğundan emin olun "anlamına gelir. Bu nedenle a == 3 ifadesinin a'nın 3'e eşit olduğundan emin olun; a 3'e eşit değilse (yani a == 3 yanlışsa), hata yapmak
Ant

5
Sadece kullanabilir miyim if not condition: raise AssertError(), neden iddia kullanmalıyım? İddiaların sadece daha kısa bir if not conditionifade biçimi olmaktan daha iyi olduğu herhangi bir koşul var mı?
alpha_989

6
@ alpha_989 a) daha kısa ve daha okunabilir, b) yorumlayıcıyı çalıştırırken onaylayıcı ifadelerini devre dışı bırakabilirsiniz (kılavuzda olduğu gibi değil if). Daha fazla bilgi için belgeleri okuyun :)
slezica

9
bu cevabı nasıl bu kadar çok oy alıyor, aslında diğerleri de nasıl cevap veriyor. soru "Python'da“ assert ”in kullanımı nedir?” diye soruyor: soruyor: ne zaman kullanılacağını ya da daha doğrusu: kullanım senaryosunun ne olduğunu assert, ancak tüm cevapları okuduktan sonra tamamen istediğim bir şey yok!
lnshi

423

Parantezlere dikkat edin. Yukarıda da belirtildiği gibi, Python 3'te asserthala bir ifade vardır , bu yüzden ile benzer şekilde print(..), kişi aynı şeyi assert(..)veya için tahmin edebilir, raise(..)ancak yapmamalısınız.

Bu önemlidir çünkü:

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

aksine, çalışmayacak

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

Birincisinin işe yaramamasının nedeni, bool( (False, "Houston we've got a problem") )değerlendirmektir True.

İfadede assert(False), bunlar sadece Falseiçeriklerini değerlendiren gereksiz parantezler . Ancak assert(False,)parantezler artık bir demettir ve boş olmayan bir demet Trueboole bağlamında değerlendirilir .


18
Buraya parens ve takip mesajı hakkında tam bilgi aramak için geldim. Teşekkürler.
superbeck

6
Ama iyi assert (2 + 2 = 5), "Houston we've got a problem"olmalı, değil mi?
SherylHohman

4
Çalışır olmadığını siz de kendiniz olduğunu çalıştırın ve görmek için deneyebilirsiniz @SherylHohman
DarkCygnus

2
İnsanların genellikle PEP 8 uyumlu örtük satır devamı için parantez kullandığını unutmayın. Ayrıca, tupllerin parantez tarafından değil, virgülün varlığı ile tanımlandığını unutmayın (tuples'ın parens ile ilgisi yoktur. Operatör Önceliği).
cowbert

4
assert (2 + 2 = 5), "Houston we've got a problem"işe yaramaz ... ama iddia deyimiyle hiçbir ilgisi yoktur, ki bu iyidir. Durumunuz çalışmaz çünkü bir koşul değildir. Bir saniye eksik =.
n1k31t4

133

Diğer cevapların belirttiği gibi, assertbelirli bir koşul doğru değilse bir istisna atmaya benzer. Önemli bir fark, kodunuzu optimizasyon seçeneğiyle derlerseniz assert ifadelerinin yok sayılmasıdır -O. Dokümantasyon söylüyor assert expressiondaha iyi eşdeğer olarak tarif edilebilir

if __debug__:
   if not expression: raise AssertionError

Kodunuzu kapsamlı bir şekilde test etmek, ardından onaylama durumlarınızın hiçbirinin başarısız olmamasından memnun olduğunuzda optimize edilmiş bir sürüm yayınlamak istiyorsanız bu yararlı olabilir - optimizasyon açıkken __debug__değişken Yanlış olur ve koşullar değerlendirilmeyi durduracaktır. Bu özellik, eklere güveniyorsanız ve kaybolduklarının farkında değilseniz sizi de yakalayabilir.


Bu, belirli bir değişken veya doğru girişin (programın yazıldığı sözleşmeye göre) kullanıcı tarafından çalıştırıldığında programın çökmesine neden olabileceği anlamına gelir (kullanıcı, programı), bunun yerine kullanmalısınız if Not Error: raise Exception(“ this is a error”)? Bu şekilde, program hala kullanıcı çalıştırdığında, hatanın kaynağını gösterecektir ..
alpha_989

Öte yandan, programın yanlış mantık / kodun uygulanması (ancak programın kullanıcısına yapılan sözleşmeye göre bir girdi nedeniyle değil) nedeniyle hata vereceğini düşünüyorsanız, assertifadeyi kullanmalısınız ? Buradaki varsayım, program son kullanıcıya bırakıldığında, -O bayrağını kullandığınız ve böylece tüm hataların kaldırıldığı varsayılacağıdır. Bu nedenle, herhangi bir hata veya program çökmesi, sözleşmeye göre geçerli olan, ancak program tarafından işlenemeyen programa girilmesinden kaynaklanır. Bu yüzden kullanıcıyı bu şekilde uyarmalıdır.
alpha_989

@ alpha_989 bu kesinlikle doğru. İddiaları, yalnızca geliştirici olarak size yardımcı olduğunu düşündüğünüz şeyin gerçekten doğru olduğundan emin olmak için size yardımcı olan akıl sağlığı kontrolleri olarak düşünmeyi seviyorum.
Christopher Shroba

52

Python'daki bir iddianın amacı, geliştiricileri bir programdaki kurtarılamaz hatalar hakkında bilgilendirmektir .

Onaylamaların, kullanıcının düzeltici eylemde bulunabileceği (veya yalnızca tekrar deneyebileceği) “dosya bulunamadı” gibi beklenen hata durumlarını göstermesi amaçlanmamıştır.

Buna bakmanın bir başka yolu, iddiaların kodunuzda dahili öz denetimler olduğunu söylemektir . Bazı koşulları kodunuzda imkansız olarak ilan ederek çalışırlar . Bu koşullar geçerli değilse, programda bir hata olduğu anlamına gelir.

Programınız hatasızsa, bu koşullar hiçbir zaman gerçekleşmez. Ancak bunlardan biri meydana gelirse, program size tam olarak hangi “imkansız” durumun tetiklendiğini söyleyen bir iddiayla hata verecektir. Bu, programlarınızdaki hataları izlemeyi ve düzeltmeyi çok daha kolay hale getirir.

İşte yazdığım Python'un iddialarına dair bir öğreticiden bir özet :

Python'un assert ifadesi, çalışma zamanı hatalarını ele almak için bir mekanizma değil, bir hata ayıklama yardımcısıdır. İddiaları kullanmanın amacı, geliştiricilerin bir hatanın olası temel nedenini daha hızlı bulmasını sağlamaktır. Programınızda bir hata olmadığı sürece bir onaylama hatası asla yükseltilmemelidir.


Makale için teşekkürler. İfadeyi assertve bunu ne zaman kullanacağınızı anlamak çok yararlı . Makalede tanıttığınız bazı terimleri anlamaya çalışıyorum.
alpha_989

Buradaki açıklamaları göndereceğimi düşündüm, bu yüzden açıklamalardan çok daha fazla insan yararlanabilir. Sorular çok safsa özür dilerim.
alpha_989

Bağladığınız blogunuzda, `0 iddiası <<fiyat <= ürün ['fiyat'] 'ın doğru olduğunu ancak` assert user.is_admin ()' i kullanarak 'Silme için yönetici ayrıcalıklarına sahip olmanız gerektiğini' belirttiğiniz bir örnek verdiniz `` ve assert store.product_exists(product_id), 'Unknown product id'iyi bir uygulama değildir, çünkü hata ayıklama kapalıysa, userolmasa bile adminürünü silebilir. Dikkate musunuz assert user.is_admin()bir şekilde unrecoverablehata? Bu neden bir değil self-check?
alpha_989

Bunu 'user.is_admin düşünürsek () `Bir kullanıcı girişi ve dolayısıyla bir in kullanılmaması gerekir assert statementcant, priceaynı zamanda bir kullanıcı girişi düşünülebilir? Neden assert user.is_admin()veri doğrulaması olarak düşünüyorsunuz assert price?
alpha_989

1
@LaryxDecidua Hayır, sadece web sitemde okuyabilirsiniz, öğretici herkese açıktır. Haber bülteni ile ilgilenmiyorsanız kaçış tuşuna basın veya küçük "x" sembolüne tıklayın. Umarım bu yardımcı olur :-)
dbader

51

Diğerleri zaten belgelere bağlantılar vermiştir.

Etkileşimli bir kabukta aşağıdakileri deneyebilirsiniz:

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

İlk ifade hiçbir şey yapmaz, ikincisi ise bir istisna oluşturur. Bu ilk ipucudur: varsayımlar, kodunuzun belirli bir pozisyonunda (genellikle, başlangıç ​​(ön koşullar) ve bir fonksiyonun sonu (son koşullar)) doğru olması gereken koşulları kontrol etmek için yararlıdır.

Ekler aslında çok kullanışlı bir mühendislik uygulaması olan sözleşmeyle programlamaya son derece bağlıdır:

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


Yani bu, iddia (2> 5) gibi bir durumda kodu kontrol edebileceğimiz ve devam eden başka bir hataya yol açabileceğimiz anlamına mı geliyor?

20
Parens kaybetmek, iddia bir işlev değildir.
pillmuncher

2
Ebeveynleri kaybetmek göründüğünden daha önemlidir. Aşağıya bakınız .
Evgeni Sergeev

6
Assert aslında (sözleşmelerden çok önce), programcıların doğru programlar oluşturma konusunda oldukça korkutucu bir görevle nasıl başa çıkabileceğine dair en eski yazılardan birini yazdığında Turing'e kadar uzanır. Bu programın bulunması okuyucu için bir alıştırma olarak bırakılmıştır, çünkü tüm programcılar çalışmalarına aşina olmaktan yararlanabilir. :-) turingarchive.org
Ron Burk

17

Dokümanlar'dan:

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

Buradan daha fazlasını okuyabilirsiniz: http://docs.python.org/release/2.5.2/ref/assert.html


sadece çok açık bir şekilde ne açıklıyor beri bu yorumu seviyorum. benim sorum "Eğer düzgün bir birim testi yazdıysam, neden bir iddiaya ihtiyacım var?" bu şeyler zaten üretimde çalışmaz.
dtc

17

Assert ifadesinin iki şekli vardır.

Basit bir şekilde, assert <expression>denktir

if __debug__:
    if not <expression>: raise AssertionError

Uzatılmış biçim assert <expression1>, <expression2>, eşdeğerdir

if __debug__:
    if not <expression1>: raise AssertionError, <expression2>

16

İddialar, bir programın dahili durumunun, programcı tarafından beklendiği gibi, hataları yakalamak amacıyla kontrol edilmesinin sistematik bir yoludur. Aşağıdaki örneğe bakın.

>>> 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!
>>> 

1
Ayrıca, iddialar birim test programlarında sıklıkla kullanılabilir. stackoverflow.com/questions/1383/what-is-unit-testing
panofish

7

İşte basit bir örnek, bunu dosyaya kaydedin (diyelim ki b.py)

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


chkassert('a')

ve sonuç ne zaman $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

6

onaylamadan sonraki ifade doğruysa program devam eder, ancak onaylamadan sonraki ifade yanlışsa program hata verir. Bu kadar basit.

Örneğin:

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

4

Bu assertifade neredeyse her programlama dilinde mevcuttur. Daha sonra başka bir işlemin yan etkisi olarak değil, sorunun açık olduğu programınızın başlangıcındaki sorunları algılamaya yardımcı olur. Her zaman bir Truedurum beklerler .

Gibi bir şey yaptığınızda:

assert condition

Programa bu durumu test etmesini ve yanlışsa hemen bir hatayı tetiklemesini söylüyorsunuz.

Python'da assertifade , şuna eşittir:

if __debug__:
    if not <expression>: raise AssertionError

İsteğe bağlı bir iletiyi iletmek için genişletilmiş ifadeyi kullanabilirsiniz :

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

Python yorumlayıcısında deneyin:

>>> 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

Esas olarak assertve ififadeleri arasında geçiş yapmayı düşünenler için bunları kullanmadan önce görülmesi gereken bazı uyarılar vardır . Kullanım amacı assert, programın bir durumu doğrulaması ve hatayı atlamak için alternatif bir yol almak yerine programı hemen durdurması gereken bir değer döndürmesi durumudur:

1. Parantezler

Fark etmiş olabileceğiniz gibi, assertifade iki koşul kullanır. Dolayısıyla, do not bariz tavsiye için biri olarak bunları englobe için parantezleri kullanabilirsiniz. Böyle yaparsanız:

assert (condition, message)

Misal:

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

İlk parametre olarak bir tuple temsil eden bir assertile çalışacaksınız (condition, message)ve bu Python'da boş olmayan tuple her zaman olduğu için olurTrue . Ancak, sorunsuz olarak ayrı ayrı yapabilirsiniz:

assert (condition), "message"

Misal:

>>> 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. Hata ayıklama amacı

Eğer ne zaman kullanım assertifadesi merak ediyorsanız . Gerçek hayatta kullanılan bir örnek alın:

* Programınız kullanıcı tarafından girilen her bir parametreyi veya başka bir şeyi kontrol etme eğiliminde olduğunda:

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())

* Başka bir durum, 0 olduğunda veya belirli bir denklemde katsayı veya sabit olarak pozitif olmadığında matematik üzerindedir:

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

* veya basit bir boole uygulamasına örnek:

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

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

3. Veri işleme veya veri doğrulama

assertVeri işlemeyi veya veri doğrulamayı yürütmek için ifadeye güvenmemek son derece önemlidir, çünkü bu ifade sırasıyla Python başlatma -Oveya -OObayrak - yani değer 1, 2 ve 0 (varsayılan olarak) veya PYTHONOPTIMIZEortam değişkeni ile kapatılabilir - ortam değişkeni .

Değer 1:

* iddialar devre dışıdır;

* Derlenen dosyalar kullanılarak oluşturulan .pyouzantısı yerine .pyc;

* sys.flags.optimize1 ( True) olarak ayarlanmıştır ;

* Ve, __debug__olarak ayarlanır False;

Değer 2: bir şeyi daha devre dışı bırakır

* docstrings devre dışı;

Bu nedenle, assertbir tür beklenen veriyi doğrulamak için ifadeyi kullanmak son derece tehlikelidir, bu da bazı güvenlik sorunlarına bile işaret eder. Ardından, bazı izinleri doğrulamanız gerekiyorsa raise AuthErrorbunun yerine size tavsiye ederim . Bir ön koşullu etki olarak, assertbir kullanıcı doğrudan etkileşimde bulunmayan kütüphaneler veya modüller üzerinde programcılar tarafından yaygın olarak kullanılır.


3

C2 Wiki'de kısaca özetlendiği gibi :

Bir iddia, programda belirli bir noktadaki bir boolean ifadesidir ve programda bir hata olmadığı sürece geçerli olacaktır .

assertBelirli bir program noktasında kodu anladığınızı belgelemek için bir ifade kullanabilirsiniz . Örneğin, girdiler (önkoşullar), program durumu (değişmezler) veya çıktılar (postkoşullar) ile ilgili varsayımları veya garantileri belgeleyebilirsiniz.

İddianız başarısız olursa, bu sizin (veya halefinizin) programı yazarken yanlış anladığınız ve muhtemelen bir hata içerdiğine dair bir uyarıdır.

Daha fazla bilgi için, John Regehr'in Python ifadesi için de geçerli olan İddiaların Kullanımı hakkında harika bir blog yazısı var assert.


2

Ayrılmış bir işlevin python'da tam olarak ne yaptığını bilmek istiyorsanız, help(enter_keyword)

Ayrılmış bir anahtar kelimeyi girdiğinizden emin olun ve bunu dize olarak girin.


2

Python iddiası temel olarak kodunuzun dahili kendi kendine kontrolü için koşulu test eden bir hata ayıklama yardımcısıdır. Assert, kodunuz imkansız uç durumlara girdiğinde hata ayıklamayı gerçekten kolaylaştırır. Bu imkansız durumları kontrol edin.

Diyelim ki indirimden sonra ürünün fiyatını hesaplamak için bir işlev var:

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

Burada, indirimli_fiyat asla 0'dan küçük ve gerçek fiyattan daha büyük olamaz. Dolayısıyla, yukarıdaki koşulun ihlal edilmesi durumunda, iddia, geliştiricinin imkansız bir şey olduğunu tanımlamasına yardımcı olan bir Onaylama Hatası oluşturur.

Umarım yardımcı olur :)


2
asserthata ayıklama bağlamında kullanışlıdır, ancak hata ayıklama bağlamının dışında kullanılmamalıdır.
FluxIX

2

Kısa açıklamam:

  • assertAssertionErrorifade yanlışsa yükseltir , aksi takdirde sadece kod devam eder ve ne olursa olsun virgül varsa AssertionError: whatever after commave kod şuna benzer:raise AssertionError(whatever after comma)

Bununla ilgili bir öğretici:

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


Bu sorunun cevabı a'nın nasıl kullanılacağını assertancak ne zaman kullanılacağını (veya kullanılmayacağını) sağlamaz assert; ayrıca belirterek asserteğer engelli olabilir __debug__is Falsefaydalı olacaktır.
FluxIX

1

Pycharm'da, assertbirlikte kullanıyorsanızisinstance bir nesnenin türünü bildirmek için kullanırsanız, kodlama sırasında üst nesnenin yöntemlerine ve özniteliklerine erişmenize izin verir, otomatik olarak tamamlanır.

Örneğin self.object1.object2, bir MyClassnesne olduğunu varsayalım.

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

0

Diğer cevaplarda yazıldığı gibi, assert ifadeler belirli bir noktada programın durumunu kontrol etmek için kullanılır.

İlişkili mesaj, parantez veya -Oseçenek ve __debug__sabit hakkında söylenenleri tekrar etmeyeceğim . İlk elden bilgi için dokümanı da kontrol edin . Sorunuza odaklanacağım: ne işe yarar assert? Daha kesin olarak, ne zaman (ve ne zaman değil) kullanılmalıdır assert?

assertİfadeleri bir program hata ayıklamak için faydalıdır, fakat kullanıcı girişi kontrol etmek cesaretini. Ben aşağıdaki kural kullanın: Bu bir durum olmamalı tespit etmek için iddiaları tutmak . Bir kullanıcı girişi yanlış olabilir, örneğin bir şifre çok kısa, ancak bu bir durum olmamalıdır . Bir dairenin çapı yarıçapından iki kat daha büyük değilse, bu durumda olmalısınız .

En ilginç olanı assert, beynimin kullanımı, B. Meyer tarafından [Nesne Odaklı Yazılım İnşası] 'nda açıklanan sözleşme ile programlamadan esinlenmiştir ( https://www.eiffel.org/doc/eiffel/Object-Oriented_Software_Construction% 2C_2nd_Edition ) ve [Eiffel programlama dili] 'nde ( https://en.wikipedia.org/wiki/Eiffel_(programming_language ) uygulanmaktadır. İfadeyi kullanarak programlamayı sözleşmeyle tam olarak taklit edemezsiniz assert, ancak niyeti korumak ilginçtir.

İşte bir örnek. Bir headişlev yazmanız gerektiğini düşünün ([ headHaskell'deki işlev gibi ) ( http://www.zvon.org/other/haskell/Outputprelude/head_f.html ). Belirtilen özellikler: "liste boş değilse, listenin ilk öğesini döndür". Aşağıdaki uygulamalara bakın:

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

Ve

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

(Evet, bu şu şekilde yazılabilir return xs[0] if xs else None, ama mesele bu değil) .

Liste boş değilse, her iki işlev de aynı sonuca sahiptir ve bu sonuç doğrudur:

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

Dolayısıyla, her iki uygulama da (umarım) doğrudur. Boş bir listenin baş öğesini almaya çalıştığınızda farklıdırlar:

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

Fakat:

>>> head2([]) is None
True

Yine, her iki uygulama da doğrudur, çünkü kimse bu işlevlere boş bir liste iletmemelidir ( spesifikasyonun dışındayız ). Bu yanlış bir çağrıdır, ancak böyle bir çağrı yaparsanız her şey olabilir. Bir işlev bir istisna oluşturur, diğeri özel bir değer döndürür. En önemlisi: bu davranışa güvenemeyiz . Eğer xsboş, işe yarayacak:

print(head2(xs))

Ancak bu programın çökmesine neden olacaktır:

print(head1(xs))

Bazı sürprizlerden kaçınmak için, bir işleve beklenmedik bir argüman aktardığımda bilmek isterim. Başka bir deyişle: Gözlenebilir davranışın ne zaman güvenilir olmadığını bilmek istiyorum, çünkü spesifikasyona değil uygulamaya bağlıdır. Tabii ki, özellikleri okuyabilirim, ancak programcılar her zaman belgeleri dikkatlice okumaz.

Aşağıdaki etkiyi elde etmek için koda şartname eklemek için bir yol olsaydı düşünün: şartnameyi ihlal ettiğimde, örneğin boş bir liste geçirerek head, bir uyarı alıyorum. Bu, doğru (yani şartnameye uygun) bir program yazmak için çok yardımcı olacaktır. Ve işte assert sahneye giriyor:

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

Ve

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

Şimdi, elimizde:

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

Ve:

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

Not head1bir atar AssertionError, bir değil IndexError. Bu önemlidir çünkü a herhangi bir çalışma zamanı hatası AssertionErrordeğildir : spesifikasyonun ihlal edildiğine işaret eder. Bir uyarı istedim ama bir hata alıyorum. Neyse ki, kontrolü ( seçeneği kullanarak ) devre dışı bırakabilirim , ancak kendi risklerim altında. Bunu yapacağım bir kaza gerçekten pahalı ve en iyisini umuyorum. Programımın bir kara delikten geçen bir uzay gemisine gömüldüğünü düşünün. İddiaları devre dışı bırakacağım ve programın mümkün olduğunca uzun süre çökmeyecek kadar sağlam olduğunu umuyorum.-O

Bu örnek yalnızca önkoşullarla ilgiliydi, ancak assertpostconditions'ı (dönüş değeri ve / veya durum) ve değişmezleri (bir sınıfın durumu) kontrol etmek için kullanabilirsiniz . Koşulları ve değişmezleri kontrol etmenin asserthantal olabileceğini unutmayın :

  • son koşullar için, bir değişkene dönüş değeri atamanız ve belki de bir yöntemle uğraşıyorsanız nesnenin iniial durumunu saklamanız gerekir;
  • değişmezler için, bir yöntem çağrısından önce ve sonra durumu kontrol etmeniz gerekir.

Eiffel kadar sofistike bir şeye sahip olmayacaksınız, ancak bir programın genel kalitesini artırabilirsiniz.


Özetlemek gerekirse, bu assertbir durumun olmaması gereken durumları tespit etmek için uygun bir yoldur . Şartnamenin ihlalleri (örneğin boş bir listenin geçilmesi head) birinci sınıftır, bu olmamalıdır . Bu nedenle, assertifade beklenmedik bir durumu tespit etmek için kullanılabilse de, spesifikasyonun yerine getirilmesini sağlamak ayrıcalıklı bir yoldur. assertKodu belirtmek üzere ifadeye ekledikten sonra , yanlış argümanlar, yanlış dönüş değerleri, bir sınıfın yanlış durumları ... rapor edileceği için programın kalitesini iyileştirdiğinizi umuyoruz.


-2

format: assert İfade [, bağımsız değişkenler] Assert bir ifadeyle karşılaştığında, Python ifadeyi değerlendirir. İfade doğru değilse bir istisna ortaya çıkar (assertionError). Onaylama başarısız olursa Python, AssertionError için bağımsız değişken olarak ArgumentExpression kullanır. AssertionError istisnaları, try-hariç ifadesi kullanılarak diğer istisnalar gibi yakalanabilir ve işlenebilir, ancak işlenmezse programı sonlandıracak ve bir geri izleme üretecektir. Misal:

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)    

Yukarıdaki kod yürütüldüğünde aşağıdaki sonucu verir:

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!    

-2
def getUser(self, id, Email):

    user_key = id and id or Email

    assert user_key

Fonksiyon çağrısında parametrelerin iletildiğinden emin olmak için kullanılabilir.


1
Bu işe yarayacak, ancak anladığım kadarıyla, kullanıcı girişini kontrol etmek için varsayımlar kullanılmamalıdır, çünkü çalışma zamanında kapatılabilirler. Kullanıcı girişini gerçekten zorlamak veya doğrulamak istiyorsanız, if not user_key: raise ValueError()Son 2 paragrafı burada kontrol edin: wiki.python.org/moin/UsingAssertionsEffective
alpha_989

assertEğer doğrulama ya dışarı çıkarılabilir çünkü giriş doğrulama için kullanılmamalıdır __debug__olup False. Ayrıca hata ayıklama olmayan amaçlarla iddiaları kullanmak, insanların elde edilen sonuçları yakalamasına neden olabilir AssertionError, bu da hata ayıklamayı daha az yerine daha zor hale getirebilir.
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
>>> 

-4

Temel olarak assert anahtar kelime anlamı, eğer koşul doğru değilse, o zaman başka bir iddia hatasıyla, örneğin python'da devam etmesidir.

Kod-1

a=5

b=6

assert a==b

ÇIKTI:

assert a==b

AssertionError

Kod-2

a=5

b=5

assert a==b

ÇIKTI:

Process finished with exit code 0

2
lütfen kodunuzu doğru şekilde biçimlendirin. ayrıca, bu önceki yanıtlarda nasıl gelişir?
c2huc2hu

açıklamamda herhangi bir sorun var mı?
ujjwal_bansal

açıklamanız mevcut cevaplara hiçbir şey eklemez ve zayıf dilbilgisi okumayı zorlaştırır. cevaplanacak sorular arıyorsanız, yeni soru beslemesine göz atmayı düşünün.
c2huc2hu

Verilen cevap nasıl kullanılacağına assertcevap verir , ancak ne zaman kullanılacağını (veya kullanılmayacağını) anlamaz assert.
FluxIX
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.