Başka denemenin var olmasının nedeni nedir?
Bir tryblok, beklenen bir hatayı işlemenizi sağlar. exceptBlok sadece işlemek için hazırlanan özel durumları yakalamak gerekir. Beklenmeyen bir hatayı işlerseniz, kodunuz yanlış bir şey yapabilir ve hataları gizleyebilir.
elseHerhangi bir hata yoksa bir yan tümce yürütülür ve bu kodu tryblokta 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 elseve finally. Yani aslında try-except-else-finally.
elseyalnızca tryblokta 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 elsealternatifle (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 elseblok trybunun 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 tryblokta bırakmak bu hatayı gizleyecektir.
tryKodumuz 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 Exceptionhata olduğunu görebiliriz , ancak Python bunlardan bazılarını bitiş fordö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 raisekorumak 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 .