python parantezli ve parantezsiz iddia


105

İşte dört basit iddia çağrısı:

>>> assert 1==2
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
AssertionError

>>> assert 1==2, "hi"
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
AssertionError: hi

>>> assert(1==2)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
AssertionError

>>> assert(1==2, "hi")

Sonuncunun bir hata oluşturmadığını unutmayın. Bu davranışa neden olan, assert'i parantezli veya parantezsiz çağırmak arasındaki fark nedir? Benim pratiğim parantez kullanmak, ancak yukarıdakiler kullanmamam gerektiğini gösteriyor.


Faydalı cevaplar için teşekkürler. Anahtar sözcükler ve yerleşik işlevler arasındaki ayrım ince görünüyor. Parenlerin
gaefan

2
Bir fark, yerleşik işlevleri yeniden tanımlayabilmeniz, ancak bunu anahtar kelimelerle yapamamanızdır (eskisinin iyi bir fikir olması değil).
gaefan

İşlev ve anahtar kelime ayrımı değil, işlev çağrısı vs deyimi . (örneğin - yazdırma eskiden bir ifade idi ve parantez olmadan çalıştı).
Tomasz Gandor

Yanıtlar:


130

Sonuncusu , IDLE aracılığıyla değil, tam bir tercüman aracılığıyla çalıştırırsanız assertsize bir uyarı ( SyntaxWarning: assertion is always true, perhaps remove parentheses?) verirdi . Çünkü assertbir anahtar kelime ve bir fonksiyondur, aslında ilk argüman olarak bir demet içinde geçen ve ikinci argüman kapalı ayrılıyor.

Boş olmayan tupleların şu şekilde değerlendirildiğini hatırlayın Trueve iddia mesajı isteğe bağlı olduğundan, esasen assert Trueyazarken aradınız assert(1==2, "hi").


10
Bunun nedeni, assert (1==2)tek bir ifadenin etrafındaki parantezlerin otomatik olarak bir demet oluşturmamasıdır; Eğer yaptıysan # 4 ile aynı davranışı elde edersin assert (1==2,). Bunun print ('foo', 'bar')yerine yaparsanız aynı şey olur print 'foo', 'bar';
dizinin çıktığını

Formdaki ifadelerin assert(test, message)muhtemelen yanlış ve kesinlikle kafa karıştırıcı olduğunu vurgulamakta fayda var. Parantez yok!
tcarobruce

19
Öyleyse, uzun bir assert ifadesini girmenin doğru yolu nedir, wrt PEP8? İmkansız görünüyor.
stantonk


30

Parantezi oraya çok satırlı bir iddia istediğiniz için koyarsanız, alternatif olarak satırın sonuna şöyle bir ters eğik çizgi koyabilirsiniz:

foo = 7
assert foo == 8, \
    "derp should be 8, it is " + str(foo)

Baskılar:

AssertionError: "derp should be 8, it is 7

Bu python neden asserther şeyden farklı olmak zorunda?

Bence pitonik ideoloji, bir programın iddiaları açmak için özel bayrak konusunda endişelenmeden kendi kendini düzeltmesi gerektiğidir. İddiaları kapatmanın cazibesi çok büyük ve bu nedenle kullanımdan kaldırılıyor.

Ben piton senin sıkıntı paylaşan asserttüm diğer piton programlama yapılara özgü sözdizimi akrabası var ve bu sözdizimi yine python3 için python2 den değişti ve tekrar 3.6 piton 3.4 olarak değiştirildi. Herhangi bir sürümden başka bir sürüme geriye dönük uyumlu olmayan assert ifadeleri yapmak.

assert3. sınıf vatandaşı olan omzuna bir dokunuş, python4'te ve kesinlikle Python 8.1'de tamamen kaldırılacak.


2
İddia etmek yerine ne kullanmamız gerektiğine dair belge var mı? Assert, doğrulama için böyle bir mantıksal isim gibi görünür ve istenen davranışa sahiptir, örneğin hata durumunda özel bir mesaj gösterir.
AnneTheAgile

18

assert 1==2, "hi"assert 1==2, "hi"anahtar kelimenin ikinci parametresi olarak "hi" olarak ayrıştırılır . Bu yüzden düzgün bir şekilde hata veriyor.

assert(1==2)tek bir öğenin etrafındaki parantlar, virgülün sonunda bir virgül yoksa bir demet oluşturmadığından, assert (1==2)hangisinin özdeş olduğu şeklinde ayrıştırılır .assert 1==2(1==2,)

assert(1==2, "hi")olarak ayrıştırılır assert (1==2, "hi"), bu bir hata vermez çünkü boş (False, "hi")olmayan bir demet yanlış bir değer değildir ve anahtar kelimeye sağlanan ikinci bir parametre yoktur.

assertPython'da bir işlev olmadığı için parantez kullanmamalısınız - bu bir anahtar kelimedir.


14

Bunu yapmadan assert ifadesini kırabilirsiniz \:

foo = 7
assert foo == 8, (
    'derp should be 8, it is ' + str(foo))

Veya daha uzun bir mesajınız varsa:

foo = 7
assert foo == 8, (
    'Lorem Ipsum is simply dummy text of the printing and typesetting '
    'industry. Lorem Ipsum has been the industry\'s standard dummy text '
    'ever since the 1500s'
)

1
İlginç fikir. Devam etmek için ters eğik çizgilerden nefret ediyorum ve bu, bir yardımcı program işlevine (benim çözümümdü) iddiayı sarmalamaya bir alternatif.
Tomasz Gandor

1

Aşağıdaki python dokümanından alıntılanmıştır

Assert deyimleri, bir programa hata ayıklama iddiaları eklemenin uygun bir yoludur:

assert_stmt ::= "assert" expression ["," expression]

Basit form, ifade ifadesi, eşdeğerdir if __debug__: if not expression: raise AssertionError

Genişletilmiş biçim, assert expression1, expression2 , eşdeğerdir if __debug__: if not expression1: raise AssertionError(expression2)

Yani burada parantez kullandığınızda, basit formu kullanıyorsunuz ve ifade bir demet olarak değerlendiriliyor, bu da bool'a dönüştürüldüğünde her zaman True

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.