Python'da iddiaları nasıl devre dışı bırakırım?
Yani, bir iddia başarısız olursa, onun bir atmasını AssertionError
değil, devam etmesini istemiyorum .
Bunu nasıl yaparım?
Yanıtlar:
Python'da iddiaları nasıl devre dışı bırakırım?
Tek bir işlemi, ortamı veya tek bir kod satırını etkileyen birden çok yaklaşım vardır.
Her birini gösteriyorum.
Kullanılması -O
bayrağı (sermaye O) bir işlemdeki tüm assert ifadeleri devre dışı bırakır.
Örneğin:
$ python -Oc "assert False"
$ python -c "assert False"
Traceback (most recent call last):
File "<string>", line 1, in <module>
AssertionError
Devre dışı bırakmakla, onu takip eden ifadeyi de çalıştırmadığını kastettiğime dikkat edin:
$ 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
Bu bayrağı ayarlamak için bir ortam değişkeni de kullanabilirsiniz.
Bu, ortamı kullanan veya miras alan her süreci etkileyecektir.
Örneğin, Windows'ta ortam değişkenini ayarlama ve ardından temizleme:
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
Unix'te aynı ( ilgili işlevsellik için set ve unset kullanarak )
Sorunuza devam edin:
bir iddia başarısız olursa, bir AssertionError atmasını değil, devam etmesini istiyorum.
Başarısız olan kodun kullanılmasını istiyorsanız, kontrol akışının onaylamaya ulaşmamasını sağlayabilirsiniz, örneğin:
if False:
assert False, "we know this fails, but we don't get here"
veya onaylama hatasını yakalayabilirsiniz:
try:
assert False, "this code runs, fails, and the exception is caught"
except AssertionError as e:
print(repr(e))
hangi yazdırır:
AssertionError('this code runs, fails, and the exception is caught')
ve ele aldığınız noktadan devam edeceksiniz AssertionError
.
Bunun gibi bir iddia ifadesi:
assert expression #, optional_message
Eşdeğerdir
if __debug__:
if not expression: raise AssertionError #(optional_message)
Ve,
yerleşik değişken
__debug__
, optimizasyon istendiğindeTrue
normal koşullar altındadırFalse
(komut satırı seçeneği-O
).
ve Ötesi
'A atamalar
__debug__
yasa dışıdır. Yerleşik değişkenin değeri, yorumlayıcı başladığında belirlenir.
Kullanım belgelerinden:
Temel optimizasyonları açın. Bu, derlenmiş (bayt kodu) dosyalar için dosya adı uzantısını .pyc'den .pyo'ya değiştirir. Ayrıca bkz. PYTHONOPTIMIZE.
ve
Bu boş olmayan bir dizeye ayarlanırsa,
-O
seçeneği belirtmeye eşdeğerdir . Bir tam sayıya ayarlanırsa,-O
birden çok kez belirtmeye eşdeğerdir .
if False: assert False
) Veya Onaylama hatasını yakalayabilirsiniz. Seçimleriniz bunlar. Sorunuzu yanıtlamak için yanıtı güncelledi.
foo()
kapalı ve anahtarlama iddialar: with skip_assertion(): foo()
. Bunun yararı, işleve başka bir bayrak eklemem
Assert
nesneleri Pass
nesnelerle değiştirin ). Bir bağlam yöneticisi bunun için doğrudan çalışmaz, ancak bu şekilde dekore edilmiş işlevleri kullanan bir tür mekanizmaya sahip olabilirsiniz. Ne olursa olsun, tavsiye etmiyorum. Bunu yapmak istemenizin nedeninin kontrol etmediğiniz kodu aramanız ve AssertionErrors'ı almanız olduğundan şüpheleniyorum. Öyleyse muhtemelen farklı bir düzeltme bulmanız gerekir.
Python'u -O bayrağıyla çağırın:
test.py:
assert(False)
print 'Done'
Çıktı:
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
Zaten verilen iki cevap Hem (biriyle Python çağrı geçerlidir -O
veya -OO
komut satırında).
İşte aralarındaki fark:
-O
Temel optimizasyonları açın. Bu, derlenmiş (bayt kodu) dosyalar için dosya adı uzantısını .pyc'den .pyo'ya değiştirir.
-OO
Optimizasyonlara ek olarak dokümanları atın -O
.
Kullanım python -O
:
$ python -O
>>> assert False
>>>
You should DEĞİL devre dışı (çoğu) iddialar. Dikkat başka yerde olduğunda, beklenmedik hataları yakalarlar. "On'un gücü" ndeki Kural 5'e bakın .
Bunun yerine, aşağıdaki gibi bazı pahalı iddia kontrollerini koruyun:
import logging
logger = logging.getLogger(__name__)
if logger.getEffectiveLevel() < logging.DEBUG:
ok = check_expensive_property()
assert ok, 'Run !'
Önemli iddiaları tutmanın ve assert
ifadelerin optimize edilmesine izin vermenin bir yolu, onları bir seçim ifadesi içinde yükseltmektir:
if foo_is_broken():
raise AssertionError('Foo is broken!')
__debug__
ama buna izin verilmiyor.