Bir satırda birden fazla istisna yakalama (blok hariç)


2756

Yapabileceğimi biliyorum:

try:
    # do something that may fail
except:
    # do this if ANYTHING goes wrong

Bunu da yapabilirim:

try:
    # do something that may fail
except IDontLikeYouException:
    # say please
except YouAreTooShortException:
    # stand on a ladder

Ama aynı şeyi iki farklı istisna içinde yapmak istersem, şu anda aklıma gelen en iyi şey bunu yapmaktır:

try:
    # do something that may fail
except IDontLikeYouException:
    # say please
except YouAreBeingMeanException:
    # say please

Böyle bir şey yapabilmenin herhangi bir yolu var mı (her iki istisnada da eylem yapmak olduğundan say please):

try:
    # do something that may fail
except IDontLikeYouException, YouAreBeingMeanException:
    # say please

Şimdi bu sözdizimiyle eşleştiği için gerçekten işe yaramaz:

try:
    # do something that may fail
except Exception, e:
    # say please

Dolayısıyla, iki ayrı istisnayı yakalama çabam tam olarak gerçekleşmiyor.

Bunu yapmanın bir yolu var mı?


6
Python 3'te, ikincisinin artık geçerli sözdizimi olmadığını unutmayın.
gerrit

Yanıtlar:


3724

Gönderen Python Belgeler :

Dışlama yantümcesi, birden çok istisnayı parantez içine alınmış bir demet olarak adlandırabilir, örneğin

except (IDontLikeYouException, YouAreBeingMeanException) as e:
    pass

Veya yalnızca Python 2 için:

except (IDontLikeYouException, YouAreBeingMeanException), e:
    pass

İstisnayı virgülle değişkenden ayırmak yine de Python 2.6 ve 2.7'de çalışır, ancak artık kullanımdan kaldırılmıştır ve Python 3'te çalışmaz; şimdi kullanmalısınız as.


9
Ben denedim ... ile list, ve sonuçlandı a TypeError. Görünüşe göre hatalar tuplebeklendiği gibi çalışmak için bir olması gerekir .
BallpointBen

4
Bu durumda bir grubun gerekli olduğunu belgelediğini açıkça gördüğünüzde neden bir liste kullandınız?
mechanical_meat

6
"Parantezli demet" in sadece sözdizimsel olup olmadığı veya iyi niyetli bir demet gerekip gerekmediği belli değildi. "Parenthesized" yanıltıcıdır, çünkü başka bir yerde parantez olmadan bir demet oluşturabilir ve sonra bunu exceptsatırda kullanabilirsiniz. Sadece exceptsatırda oluşturulursa parantez içine alınır .
BallpointBen

5
@JosephBani, ya jeneratör ifadeleri?
jammertheprogrammer

12
@JosephBani Bu hiç doğru değil. In 2 + (x * 2), (x * 2)kesinlikle bir demet değil. Parantezler genel bir gruplama yapısıdır. Bir demetin belirleyici özelliği virgül içermesidir - Python belgelerine bakın : "Aslında parantez yerine bir demet oluşturan virgül olduğuna dikkat edin."
Soren Bjornstad

314

Bir satırda birden fazla istisnayı nasıl yakalarım (blok hariç)

Bunu yap:

try:
    may_raise_specific_errors():
except (SpecificErrorOne, SpecificErrorTwo) as error:
    handle(error) # might log or have some other default behavior...

Hata nesnesini bir ada atamak için virgül kullanan eski sözdizimi nedeniyle parantez gerekir. asAnahtar kelime atama için kullanılır. Hata nesnesi için herhangi bir isim kullanabilirsiniz, ben errorşahsen tercih ederim .

En iyi pratik

Bunu şu anda ve Python ile uyumlu bir şekilde yapmak için, İstisnaları virgülle ayırmanız ve bir istisna türünü yakalanacak İstisna türünü izleyerek istisna örneğini bir değişken adına atayan önceki sözdiziminden ayırt etmek için parantez ile sarmanız gerekir. virgül.

İşte basit kullanım örneği:

import sys

try:
    mainstuff()
except (KeyboardInterrupt, EOFError): # the parens are necessary
    sys.exit(0)

Karşılaştığımda tam yığın izini beklediğim hataları gizlemekten kaçınmak için yalnızca bu istisnaları belirtiyorum.

Bu, burada belgelenmiştir: https://docs.python.org/tutorial/errors.html

İstisnayı bir değişkene atayabilirsiniz ( eyaygındır, ancak uzun istisna işlemeniz varsa veya IDE'niz yalnızca benimki gibi bundan daha büyük seçimleri vurgularsa daha ayrıntılı bir değişkeni tercih edebilirsiniz.) Örneği bir args özniteliğine sahiptir. İşte bir örnek:

import sys

try:
    mainstuff()
except (KeyboardInterrupt, EOFError) as err: 
    print(err)
    print(err.args)
    sys.exit(0)

Python 3'te, blok sonuçlandığında errnesnenin kapsam dışında kaldığını unutmayın except.

Kaldırıldı

Hatayı virgülle atayan bir kod görebilirsiniz. Python 2.5 ve önceki sürümlerde kullanılabilen tek form olan bu kullanım kullanımdan kaldırılmıştır ve kodunuzun Python 3'te ileriye doğru uyumlu olmasını istiyorsanız, sözdizimini yeni formu kullanacak şekilde güncellemelisiniz:

import sys

try:
    mainstuff()
except (KeyboardInterrupt, EOFError), err: # don't do this in Python 2.6+
    print err
    print err.args
    sys.exit(0)

Kod tabanınızda virgül adı ataması görürseniz ve Python 2.5 veya üstünü kullanıyorsanız, yeni sürüme geçerek yeni sürüme geçin, böylece yükseltme yaptığınızda kodunuz uyumlu kalır.

suppressbağlam yöneticisi

Kabul edilen cevap gerçekten minimum 4 satır koddur:

try:
    do_something()
except (IDontLikeYouException, YouAreBeingMeanException) as e:
    pass

try, except, passHatlar tek bir şekilde ele alınabilir Python 3.4 uygun bastırmak bağlam yöneticisi :

from contextlib import suppress

with suppress(IDontLikeYouException, YouAreBeingMeanException):
     do_something()

passBelirli istisnalar dışında kullanmak istediğinizde suppress.


2
İyi ilavesi suppresssadece yapmaktan daha okunabilir bir sürü passüzerindeexcept
Mache

50

Gönderen Python belgelerine -> 8.3 İstisnalar :

Bir tryifadenin, farklı istisnalar için işleyicileri belirtmek üzere yan tümcesi dışında birden fazla değeri olabilir. En çok bir işleyici çalıştırılır. İşleyiciler, aynı try deyiminin diğer işleyicilerinde değil, yalnızca ilgili try yan tümcesinde oluşan istisnaları işler. Dışlama yantümcesi, birden çok istisnayı parantez içine alınmış bir demet olarak adlandırabilir, örneğin:

except (RuntimeError, TypeError, NameError):
    pass

Bu kümenin etrafındaki parantezlerin gerekli olduğuna dikkat edin, çünkü ValueError, e:normalde except ValueError as e:modern Python'da yazılanlar için kullanılan sözdizimi (aşağıda açıklanmıştır). Eski sözdizimi geriye dönük uyumluluk için hala desteklenmektedir. Bu except RuntimeError, TypeError, eşdeğer değil, except (RuntimeError, TypeError):ama except RuntimeError as TypeError:istediğiniz şey değildir.


35

Sık sık çok sayıda istisna kullanıyorsanız, bir demet önceden tanımlayabilirsiniz, böylece bunları birçok kez yeniden yazmak zorunda kalmazsınız.

#This example code is a technique I use in a library that connects with websites to gather data

ConnectErrs  = (URLError, SSLError, SocketTimeoutError, BadStatusLine, ConnectionResetError)

def connect(url, data):
    #do connection and return some data
    return(received_data)

def some_function(var_a, var_b, ...):
    try: o = connect(url, data)
    except ConnectErrs as e:
        #do the recovery stuff
    blah #do normal stuff you would do if no exception occurred

NOTLAR:

  1. Ayrıca, önceden tanımlanmış gruptaki diğer istisnaları da yakalamanız gerekiyorsa, blok hariç başka bir istisna tanımlamanız gerekir.

  2. Eğer global bir değişkeni tolere edemezseniz, main () 'de tanımlayın ve gereken yere aktarın ...


17

Bunu yapmanın yollarından biri ..

try:
   You do your operations here;
   ......................
except(Exception1[, Exception2[,...ExceptionN]]]):
   If there is any exception from the given exception list, 
   then execute this block.
   ......................
else:
   If there is no exception then execute this block. 

ve başka bir yol, exceptblok tarafından yürütülen görevi gerçekleştiren bir yöntem oluşturmak ve yazdığınız tüm exceptblok boyunca çağırmaktır .

try:
   You do your operations here;
   ......................
except Exception1:
    functionname(parameterList)
except Exception2:
    functionname(parameterList)
except Exception3:
    functionname(parameterList)
else:
   If there is no exception then execute this block. 

def functionname( parameters ):
   //your task..
   return [expression]

İkincisinin bunu yapmanın en iyi yolu olmadığını biliyorum, ama sadece bu şeyi yapmanın birkaç yolunu gösteriyorum.


İkincisini kullanıyorum çünkü her birinin farklı şekilde işlenmesi gereken iki farklı istisna var. Bu şekilde yapmakta bir sorun mu var?
majikman

@majikman Her biri aynı işlevi çağıran birden fazla cümle içeren ikinci yöntem, kendinizi tekrarlamamaya ve aynı şeyi iki istisna için yapmaya çalıştığınızda en iyi yöntem değildir. (Bunu yapmanın doğru yolu için diğer cevaplara bakınız). Ancak, exceptistisnaları farklı işlemek istediğinizde birden fazla cümleye sahip olmak normaldir.
İsimsiz
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.