python cgi - قبض على استثناءات متعددة في سطر واحد(باستثناء الحظر)




example class (7)

بالنسبة إلى python 2.5 والإصدارات الأقدم ، يكون التركيب الصحيح هو:

except (IDontLikeYouException, YouAreBeingMeanException), e:
    print e

حيث e هو مثيل الاستثناء.

أعلم أنه يمكنني فعل ما يلي:

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

يمكنني أيضًا القيام بذلك:

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

ولكن إذا أردت أن أفعل الشيء نفسه داخل استثناءين مختلفين ، فإن أفضل ما أفكر به الآن هو القيام بذلك:

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

هل هناك أي طريقة لأفعل شيء من هذا القبيل (بما أن الإجراء الواجب اتخاذه في كلا الاستثناءين هو say please ):

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

الآن لن يعمل هذا بالفعل ، لأنه يطابق بناء الجملة من أجل:

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

لذا ، فإن مجهودي للقبض على الاستثناءين المتميزين لا يأتي بالضبط.

هل هناك طريقة للقيام بذلك؟


بيثون 2.7 تنص الوثائق على ما يلي:

قد يحتوي بيان المحاولة على أكثر من جملة باستثناء عبارة ، لتحديد معالجات للاستثناءات المختلفة. على الأكثر سيتم تنفيذ معالج واحد. تعالج معالجات فقط الاستثناءات التي تحدث في جملة المحاولة المقابلة ، وليس في معالجات أخرى من نفس جملة المحاولة. قد تشير عبارة "باستثناء جملة" إلى استثناءات متعددة باعتبارها مجموعة من علامات القوس ، على سبيل المثال:

try:
    raise ValueError("hello")
except (RuntimeError, ValueError, KeyError) as a:
    print a

لاحظ أن الأقواس الموجودة حول هذه المجموعة مطلوبة ، نظرًا لأن القيمة ValueError ، وهي: تم استخدام بناء الجملة لما هو مكتوب عادةً على أنه غير ValueError كـ e: في Python الحديث (كما هو موضح أدناه). لا يزال يتم دعم بناء الجملة القديم للتوافق مع الإصدارات السابقة. هذا يعني RuntimeError باستثناء ، TypeError غير مساوية باستثناء (RuntimeError، TypeError): ولكن باستثناء RuntimeError كـ TypeError: وهو ليس ما تريده.


كيف أقبض على استثناءات متعددة في سطر واحد (باستثناء الحظر)

افعل هذا:

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

مطلوبة الأقواس بسبب إلى بناء الجملة القديمة التي تستخدم الفواصل لتعيين كائن الخطأ إلى اسم. يتم استخدام الكلمة الأساسية للمهمة. يمكنك استخدام أي اسم لكائن الخطأ ، لكنني أفضل error شخصيًا.

افضل تمرين

للقيام بذلك بطريقة متوافقة مع بايثون حاليًا ، تحتاج إلى فصل الاستثناءات باستخدام الفواصل والتفافها مع الأقواس للتمييز من بناء الجملة السابق الذي قام بتعيين مثيل الاستثناء إلى اسم متغير باتباع نوع الاستثناء الذي يتم ضبطه باستخدام فاصلة.

إليك مثال على الاستخدام البسيط:

try:
    mainstuff()
except (KeyboardInterrupt, EOFError): # the parens are necessary
    quit(0)

أنا تحديد هذه الاستثناءات فقط لتجنب إخفاء الخلل ، والتي إذا واجهت أتوقع تتبع مكدس كامل من.

هذا موثق هنا: https://docs.python.org/tutorial/errors.html

يمكنك تعيين الاستثناء لمتغير ، ( e شائع ، لكنك قد تفضل متغير أكثر مطولاً إذا كان لديك استثناء طويل أو IDE يسلط الضوء فقط على اختيارات أكبر من ذلك ، كما يفعل المنجم.) يحتوي المثيل على سمة args. هنا مثال:

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

لاحظ أنه في Python 3 ، يقع كائن err خارج النطاق عند إتمام الاستثناء.

إهمال

قد ترى رمزًا يعيّن الخطأ بفاصلة. هذا الاستخدام ، وهو النموذج الوحيد المتاح في Python 2.5 والإصدارات الأقدم ، تم إيقافه ، وإذا كنت ترغب في أن تكون التعليمات البرمجية الخاصة بك متوافقة في Python 3 ، يجب عليك تحديث البنية لاستخدام النموذج الجديد:

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

إذا رأيت تعيين اسم الفاصلة في مصدر التعليمات البرمجية ، وكنت تستخدم Python 2.5 أو أعلى ، فقم بالتبديل إلى الطريقة الجديدة للقيام بذلك حتى تظل التعليمات البرمجية متوافقة عند الترقية.

مدير السياق suppress

الإجابة المقبولة هي بالفعل 4 أسطر من الكود ، كحد أدنى:

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

يمكن التعامل مع try ، except ، pass الخطوط في سطر واحد مع مدير سياق قمع ، وهي متاحة في Python 3.4 :

from contextlib import suppress

with suppress(IDontLikeYouException, YouAreBeingMeanException):
     do_something()

لذلك عندما تريد pass بعض الاستثناءات ، استخدم suppress .


إذا كنت تستخدم عددًا كبيرًا من الاستثناءات بشكل متكرر ، فيمكنك تحديد فئة ما مسبقًا ، حتى لا تضطر إلى إعادة كتابتها عدة مرات.

#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

ملاحظات:

  1. إذا كنت تحتاج أيضًا إلى التقاط استثناءات أخرى غير تلك الموجودة في المجموعة المحددة مسبقًا ، فستحتاج إلى تحديد أخرى باستثناء الحظر.

  2. إذا كنت لا تستطيع تحمل متغير عالمي ، قم بتعريفه في main () وقم بتمريره عند الحاجة ...


من وثائق Python :

قد تشير عبارة "باستثناء جملة" إلى استثناءات متعددة على أنها مجموعة مدقمة بين قوسين ، على سبيل المثال

except (IDontLikeYouException, YouAreBeingMeanException) as e:
    pass

أو ، بالنسبة إلى Python 2 فقط:

except (IDontLikeYouException, YouAreBeingMeanException), e:
    pass

سيؤدي فصل الاستثناء من المتغير باستخدام فاصلة إلى العمل في Python 2.6 و 2.7 ، ولكن يتم الآن إيقاف العمل به ولا يعمل في Python 3؛ الآن يجب أن تستخدمها.


من وثائق Python -> 8.3 معالجة الاستثناءات :

قد يحتوي بيان try على أكثر من جملة باستثناء عبارة ، لتحديد معالجات للاستثناءات المختلفة. على الأكثر سيتم تنفيذ معالج واحد. تعالج معالجات فقط الاستثناءات التي تحدث في جملة المحاولة المقابلة ، وليس في معالجات أخرى من نفس جملة المحاولة. قد تشير عبارة "باستثناء جملة" إلى استثناءات متعددة باعتبارها مجموعة من علامات القوس ، على سبيل المثال:

except (RuntimeError, TypeError, NameError):
    pass

لاحظ أن الأقواس الموجودة حول هذه المجموعة مطلوبة ، نظرًا لأن ValueError, e: تم استخدام بناء الجملة لما هو مكتوب عادةً على أنه except ValueError as e: في Python الحديث (كما هو موضح أدناه). لا يزال يتم دعم بناء الجملة القديم للتوافق مع الإصدارات السابقة. هذا يعني except RuntimeError, TypeError غير مساوية except (RuntimeError, TypeError): ولكن except RuntimeError as TypeError: وهو ليس ما تريده.


We can use an assertion fail after the method that must return an exception:

try{
   methodThatThrowMyException();
   Assert.fail("MyException is not thrown !");
} catch (final Exception exception) {
   // Verify if the thrown exception is instance of MyException, otherwise throws an assert failure
   assertTrue(exception instanceof MyException, "An exception other than MyException is thrown !");
   // In case of verifying the error message
   MyException myException = (MyException) exception;
   assertEquals("EXPECTED ERROR MESSAGE", myException.getMessage());
}




python exception exception-handling