Başka denemenin var olmasının nedeni nedir?
Bir try
blok, beklenen bir hatayı işlemenizi sağlar. except
Blok sadece işlemek için hazırlanan özel durumları yakalamak gerekir. Beklenmeyen bir hatayı işlerseniz, kodunuz yanlış bir şey yapabilir ve hataları gizleyebilir.
else
Herhangi bir hata yoksa bir yan tümce yürütülür ve bu kodu try
blokta yürütmeden beklenmedik bir hatayı yakalamaktan kaçınırsınız. Yine, beklenmedik bir hatayı yakalamak hataları gizleyebilir.
Misal
Örneğin:
try:
try_this(whatever)
except SomeException as the_exception:
handle(the_exception)
else:
return something
"Try hariç" paketi iki isteğe bağlı cümleye sahiptir else
ve finally
. Yani aslında try-except-else-finally
.
else
yalnızca try
blokta istisna yoksa değerlendirir . Aşağıdaki daha karmaşık kodu basitleştirmemizi sağlar:
no_error = None
try:
try_this(whatever)
no_error = True
except SomeException as the_exception:
handle(the_exception)
if no_error:
return something
yani bir else
alternatifle (hatalar oluşturabilir) karşılaştırırsak, kod satırlarını azalttığını ve daha okunabilir, bakımı kolay ve daha az hata kodlu bir tabanına sahip olabileceğimizi görürüz.
finally
finally
başka bir satır bir return ifadesiyle değerlendirilse bile, ne olursa olsun yürütülür.
Sahte kod ile parçalanmış
Bunu, tüm özellikleri gösteren mümkün olan en küçük biçimde yorumlarla yıkmaya yardımcı olabilir. Sözdizimsel olarak doğru olduğunu varsayalım (ancak adlar tanımlanmadığı sürece çalıştırılamaz) pseudo-code bir işlevdedir.
Örneğin:
try:
try_this(whatever)
except SomeException as the_exception:
handle_SomeException(the_exception)
# Handle a instance of SomeException or a subclass of it.
except Exception as the_exception:
generic_handle(the_exception)
# Handle any other exception that inherits from Exception
# - doesn't include GeneratorExit, KeyboardInterrupt, SystemExit
# Avoid bare `except:`
else: # there was no exception whatsoever
return something()
# if no exception, the "something()" gets evaluated,
# but the return will not be executed due to the return in the
# finally block below.
finally:
# this block will execute no matter what, even if no exception,
# after "something" is eval'd but before that value is returned
# but even if there is an exception.
# a return here will hijack the return functionality. e.g.:
return True # hijacks the return in the else clause above
Biz doğrudur olabilir kod dahil else
blok try
bunun hiçbir istisnası olsaydı çalıştırabilir, ancak nerede, yerine bloğun ne anlama kod kendisi biz anlıyorsun tür bir özel durum olur? Bunu try
blokta bırakmak bu hatayı gizleyecektir.
try
Kodumuz başarısız olursa, yüksek sesle başarısız olmasını istediğimiz ilkesi altında, beklemediğimiz istisnaları yakalamaktan kaçınmak için bloktaki kod satırlarını en aza indirmek istiyoruz. Bu en iyi uygulamadır .
İstisnaların hata olmadığı anlayışım
Python'da, istisnaların çoğu hatalardır.
İstisna hiyerarşisini pydoc kullanarak görebiliriz. Örneğin, Python 2'de:
$ python -m pydoc exceptions
veya Python 3:
$ python -m pydoc builtins
Bize hiyerarşiyi verecek. Çoğu türün Exception
hata olduğunu görebiliriz , ancak Python bunlardan bazılarını bitiş for
döngüleri ( StopIteration
) gibi şeyler için kullanıyor . Bu Python 3'ün hiyerarşisi:
BaseException
Exception
ArithmeticError
FloatingPointError
OverflowError
ZeroDivisionError
AssertionError
AttributeError
BufferError
EOFError
ImportError
ModuleNotFoundError
LookupError
IndexError
KeyError
MemoryError
NameError
UnboundLocalError
OSError
BlockingIOError
ChildProcessError
ConnectionError
BrokenPipeError
ConnectionAbortedError
ConnectionRefusedError
ConnectionResetError
FileExistsError
FileNotFoundError
InterruptedError
IsADirectoryError
NotADirectoryError
PermissionError
ProcessLookupError
TimeoutError
ReferenceError
RuntimeError
NotImplementedError
RecursionError
StopAsyncIteration
StopIteration
SyntaxError
IndentationError
TabError
SystemError
TypeError
ValueError
UnicodeError
UnicodeDecodeError
UnicodeEncodeError
UnicodeTranslateError
Warning
BytesWarning
DeprecationWarning
FutureWarning
ImportWarning
PendingDeprecationWarning
ResourceWarning
RuntimeWarning
SyntaxWarning
UnicodeWarning
UserWarning
GeneratorExit
KeyboardInterrupt
SystemExit
Bir yorumcu sordu:
Harici bir API'ye ping uygulayan bir yönteminiz olduğunu ve istisnayı API sarmalayıcı dışındaki bir sınıfta işlemek istediğinizi varsayalım, e'nin istisna nesnesinin olduğu istisna cümlesinin altındaki yöntemden e döndürür müsünüz?
Hayır, istisnayı döndürmezsiniz, sadece yığın izini raise
korumak için çıplak bir şekilde yeniden yükseltin.
try:
try_this(whatever)
except SomeException as the_exception:
handle(the_exception)
raise
Veya Python 3'te, istisna zincirleme ile yeni bir istisna oluşturabilir ve geri izlemeyi koruyabilirsiniz:
try:
try_this(whatever)
except SomeException as the_exception:
handle(the_exception)
raise DifferentException from the_exception
Cevabımı burada ayrıntılı olarak açıklıyorum .