İstisnayı ele almadan bir deneme-dışında yapmak istediğinizde, bunu Python'da nasıl yaparsınız?
Aşağıdakiler bunu yapmanın doğru yolu mu?
try:
shutil.rmtree(path)
except:
pass
try: rob() except: run()
İstisnayı ele almadan bir deneme-dışında yapmak istediğinizde, bunu Python'da nasıl yaparsınız?
Aşağıdakiler bunu yapmanın doğru yolu mu?
try:
shutil.rmtree(path)
except:
pass
try: rob() except: run()
Yanıtlar:
try:
doSomething()
except:
pass
veya
try:
doSomething()
except Exception:
pass
Fark İlki da yakalayacak olması KeyboardInterrupt
, SystemExit
ve doğrudan elde böyle şeyler, exceptions.BaseException
değil, exceptions.Exception
.
Ayrıntılar için belgelere bakın:
try: shuti.rmtree(...) except: pass
herhangi bir hatayı kabaca bastırır ( shutil
sonuçta yanlış yazmış olsanız bile NameError
) - en azındanexcept OSError:
Genellikle ilgilendiğiniz hataları yakalamak sadece en iyi uygulama olarak kabul hâlinde. shutil.rmtree
Bunun muhtemelen OSError
:
>>> shutil.rmtree("/fake/dir")
Traceback (most recent call last):
[...]
OSError: [Errno 2] No such file or directory: '/fake/dir'
Bu hatayı sessizce yoksaymak isterseniz şunları yaparsınız:
try:
shutil.rmtree(path)
except OSError:
pass
Neden? Diyelim ki (bir şekilde) yanlışlıkla bir dize yerine bir tamsayı iletin, örneğin:
shutil.rmtree(2)
"TypeError: Unicode'a zorlama: dize veya arabellek gerekir, int bulundu" hatasını verir - muhtemelen bunu göz ardı etmek istemezsiniz, bu hata ayıklamak zor olabilir.
Eğer varsa kesinlikle tüm hataları görmezden istiyorum yakalamak Exception
çıplak ziyade except:
açıklamada. Yine neden?
Bir istisna belirtmemek , örneğin aşağıdakileri kullanan istisna da dahil olmak üzere her istisnayı yakalar :SystemExit
sys.exit()
>>> try:
... sys.exit(1)
... except:
... pass
...
>>>
Bunu, doğru şekilde çıkan aşağıdakilerle karşılaştırın:
>>> try:
... sys.exit(1)
... except Exception:
... pass
...
shell:~$
Daha iyi davranış kodu yazmak istiyorsanız, OSError
istisna çeşitli hataları temsil edebilir, ancak yukarıdaki örnekte yalnızca yok saymak istiyoruz Errno 2
, bu yüzden daha da spesifik olabiliriz:
import errno
try:
shutil.rmtree(path)
except OSError as e:
if e.errno != errno.ENOENT:
# ignore "No such file or directory", but re-raise other errors
raise
shutil.rmtree
en iyi örnek değil, çünkü sadece ignore_errors=True
bu işlev için kullanabilirsiniz ..
İstisnayı ele almadan bir deneme yakalaması yapmak istediğinizde, bunu Python'da nasıl yaparsınız?
"Elleçleme" ile ne demek istediğinize bağlıdır.
Herhangi bir işlem yapmadan yakalamak istiyorsanız, postaladığınız kod çalışacaktır.
İstisnanın yığına çıkmasını engellemeden bir istisna üzerinde işlem yapmak istediğinizi kastediyorsanız, şöyle bir şey istersiniz:
try:
do_something()
except:
handle_exception()
raise #re-raise the exact same exception that was thrown
Öncelikle Jack o'Connor'ın bu konudaki cevabını alıntıladım . Burada yazılan başvurulan konu kapatıldı:
"Python 3.4'te bunu yapmanın yeni bir yolu var:
from contextlib import suppress
with suppress(Exception):
# your code
İşte ekleyen taahhüt: http://hg.python.org/cpython/rev/406b47c64480
Ve işte yazar Raymond Hettinger, bu ve diğer her türlü Python sıcaklığından bahsediyor: https://youtu.be/OSGv2VnC0go?t=43m23s
Buna ek olarak Python 2.7 eşdeğeri:
from contextlib import contextmanager
@contextmanager
def ignored(*exceptions):
try:
yield
except exceptions:
pass
Sonra Python 3.4 gibi kullanın:
with ignored(Exception):
# your code
Tamamlamak için:
>>> def divide(x, y):
... try:
... result = x / y
... except ZeroDivisionError:
... print("division by zero!")
... else:
... print("result is", result)
... finally:
... print("executing finally clause")
Ayrıca, istisnayı şöyle yakalayabileceğinizi unutmayın:
>>> try:
... this_fails()
... except ZeroDivisionError as err:
... print("Handling run-time error:", err)
... ve istisnayı şu şekilde yeniden yükseltin:
>>> try:
... raise NameError('HiThere')
... except NameError:
... print('An exception flew by!')
... raise
... python öğreticisinden örnekler .
İstisnalar nasıl düzgün şekilde göz ardı edilir?
Bunu yapmanın çeşitli yolları var.
Bununla birlikte, örnek seçiminin genel durumu kapsayan basit bir çözümü vardır.
Onun yerine
try:
shutil.rmtree(path)
except:
pass
Bunu yap:
shutil.rmtree(path, ignore_errors=True)
Bu özel bir argüman shutil.rmtree
. Aşağıdakileri yaparak bununla ilgili yardımı görebilirsiniz ve bunun da hatalarda işlevselliğe izin verebileceğini göreceksiniz.
>>> import shutil
>>> help(shutil.rmtree)
Bu yalnızca örneğin dar durumunu kapsadığından, bu anahtar kelime bağımsız değişkenleri yoksa bunun nasıl ele alınacağını daha fazla göstereceğim.
Yukarıdakiler yalnızca örneğin dar durumunu kapsadığından, bu anahtar kelime bağımsız değişkenleri yoksa bunun nasıl ele alınacağını daha fazla göstereceğim.
suppress
İçerik yöneticisini içe aktarabilirsiniz :
from contextlib import suppress
Ancak yalnızca en özel istisnayı bastırın:
with suppress(FileNotFoundError):
shutil.rmtree(path)
Sessizce bir FileNotFoundError
:
>>> with suppress(FileNotFoundError):
... shutil.rmtree('bajkjbkdlsjfljsf')
...
>>>
Gönderen docs :
İstisnaları tamamen bastıran diğer mekanizmalarda olduğu gibi, bu bağlam yöneticisi yalnızca program yürütmeye sessizce devam etmenin yapılması gereken doğru şey olduğu bilinen çok spesifik hataları kapsamak için kullanılmalıdır.
suppress
Ve FileNotFoundError
yalnızca Python 3'te kullanılabilir olduğunu unutmayın .
Kodunuzun Python 2'de de çalışmasını istiyorsanız, bir sonraki bölüme bakın:
İstisnayı kullanmadan bir deneme / hariç yapmak istediğinizde, Python'da nasıl yaparsınız?
Aşağıdakiler bunu yapmanın doğru yolu mu?
try : shutil.rmtree ( path ) except : pass
Python 2 uyumlu kod için, pass
no-op olmayan bir ifadeye sahip olmanın doğru yoludur. Bir çıplak yaptığınızda Fakat except:
, bunu yaparken aynı şey except BaseException:
içeren GeneratorExit
, KeyboardInterrupt
ve SystemExit
, ve genel olarak, o şeyleri yakalamak istemiyorum.
Aslında, istisnayı olabildiğince isimlendirirken spesifik olmalısınız.
İşte Python (2) istisna hiyerarşisinin bir parçası ve gördüğünüz gibi, daha genel İstisnalar yakalarsanız, beklemediğiniz sorunları gizleyebilirsiniz:
BaseException
+-- SystemExit
+-- KeyboardInterrupt
+-- GeneratorExit
+-- Exception
+-- StopIteration
+-- StandardError
| +-- BufferError
| +-- ArithmeticError
| | +-- FloatingPointError
| | +-- OverflowError
| | +-- ZeroDivisionError
| +-- AssertionError
| +-- AttributeError
| +-- EnvironmentError
| | +-- IOError
| | +-- OSError
| | +-- WindowsError (Windows)
| | +-- VMSError (VMS)
| +-- EOFError
... and so on
Muhtemelen burada bir OSError yakalamak istersiniz ve belki de umursamadığınız istisna dizin yoksa.
Biz alabilirsiniz o özel hata numarayı errno
bunu yoksa kütüphane ve tekrar yükseltti:
import errno
try:
shutil.rmtree(path)
except OSError as error:
if error.errno == errno.ENOENT: # no such file or directory
pass
else: # we had an OSError we didn't expect, so reraise it
raise
Unutmayın, çıplak bir yükseltme orijinal istisnayı yükseltir, bu muhtemelen bu durumda istediğiniz şeydir. pass
İstisna işlemede açıkça kodla ihtiyacımız olmadığı için daha kısaca yazılmıştır :
try:
shutil.rmtree(path)
except OSError as error:
if error.errno != errno.ENOENT: # no such file or directory
raise
İstisnayı ele almadan bir deneme yakalaması yapmak istediğinizde, bunu Python'da nasıl yaparsınız?
Bu, istisnanın ne olduğunu yazdırmanıza yardımcı olacaktır :( yani istisnayı ele almadan yakalamayı deneyin ve istisnayı yazdırın.)
import sys
try:
doSomething()
except:
print "Unexpected error:", sys.exc_info()[0]
try:
doSomething()
except Exception:
pass
else:
stuffDoneIf()
TryClauseSucceeds()
FYI else yan tümcesi tüm istisnalardan sonra gidebilir ve yalnızca denemedeki kod bir istisnaya neden olmazsa çalıştırılır.
else
bu bağlamda iyi bir açıklama . Ve eklemek için finally
her zaman herhangi bir (veya istisna) sonra çalışır.
Birden fazla komuttaki hataları görmezden gelmem gerekiyordu ve fuckit hile yaptı
import fuckit
@fuckit
def helper():
print('before')
1/0
print('after1')
1/0
print('after2')
helper()
Python'da, diğer dile benzer istisnaları ele alıyoruz, ancak fark bazı sözdizimi farkıdır, örneğin,
try:
#Your code in which exception can occur
except <here we can put in a particular exception name>:
# We can call that exception here also, like ZeroDivisionError()
# now your code
# We can put in a finally block also
finally:
# Your code...
Genellikle sadece:
try:
doSomething()
except:
_ = ""
_ = ""
ile pass
.
shutil.rmtree(path, ignore_errors=True)
. Ancak bu çoğu işlev için geçerli değildir.