سؤال

لقد وجدت السلوك التالي على الأقل غريب:

def errors():
    try:
        ErrorErrorError
    finally:
        return 10

print errors()
# prints: 10
# It should raise: NameError: name 'ErrorErrorError' is not defined

يختفي الاستثناء عند الاستخدام return داخل finally بند.هل هذا خطأ؟هل تم توثيق ذلك في أي مكان؟

لكن السؤال الحقيقي (والإجابة التي سأضع علامة على أنها صحيحة) هو:
ما هو سبب مطوري بايثون للسماح بهذا السلوك الغريب؟

هل كانت مفيدة؟

المحلول

وسألت عن المنطق المطورين بيثون. لا أستطيع أن أتكلم بالنسبة لهم، ولكن لا تقدم أي سلوك آخر معانيها. ويمكن للوظيفة إما بإرجاع قيمة، أو أنه يمكن رفع استثناء. فإنه لا يمكن القيام بالأمرين معا. الغرض من عبارة "أخيرا" هو توفير رمز تنظيف هذا هو "مضمونة" ليتم تشغيلها، بغض النظر عن الاستثناءات. عن طريق وضع عبارة إرجاع في بند أخيرا، كنت قد أعلنت الذي تريد إرجاع قيمة، مهما كانت، بغض النظر عن الاستثناءات. إذا تصرف بيثون كما كنت طالبا ورفعت استثناء، سيكون من كسر العقد شرط "أخيرا" (لأنه سيفشل لإرجاع القيمة قلت لها بالعودة).

نصائح أخرى

يختفي الاستثناء عند الاستخدام return داخل finally بند...هل تم توثيق ذلك في أي مكان؟

إنها:

إذا كان موجودًا أخيرًا، فإنه يحدد معالج "التنظيف".يتم تنفيذ جملة المحاولة، بما في ذلك أي عبارات باستثناء و else.إذا حدث استثناء في أي من البنود ولم تتم معالجته، فسيتم حفظ الاستثناء مؤقتًا.يتم تنفيذ الجملة النهائية.إذا كان هناك استثناء محفوظ، فسيتم إعادة طرحه في نهاية الجملة الأخيرة. إذا أثارت الجملة النهائية استثناءً آخر أو نفذت عبارة إرجاع أو فاصل، فسيتم فقدان الاستثناء المحفوظ.

وهنا هو مقارنة مثيرة للاهتمام للعودة في منع أخيرا، بين - جاوة / C # / بيثون / جافا سكريبت: (<لأ href = "https://web.archive.org/web/20120426091446/http://www. gettingclever.com/2008/07/return-from-finally.html "يختلط =" نوفولو noreferrer "> أرشيف صلة )

<اقتباس فقرة>   

عودة من وأخيرا

     

واليوم فقط كنت أساعد مع بعض الأخطاء في جاوة وجاء عبر   مشكلة مثيرة للاهتمام - ماذا يحدث إذا كنت تستخدم العودة في غضون حاول / catch   بيان؟ يجب إطلاق القسم في النهاية أم لا؟ I تبسيط   المشكلة التالية مقتطف الشفرة:

     

وماذا الطباعة البرمجية التالية من؟

class ReturnFromFinally {  
 public static int a() {  
  try {  
   return 1;  
  }  
  catch (Exception e) {}  
  finally{  
   return 2;  
  }  
 }  

        public static void main(String[] args) {  
  System.out.println(a());  
        }  
}  
     

وتخميني الأولي سيكون، وأنه يجب طباعة 1، ادعو   return، لذلك أفترض، سيتم إرجاع واحد. ومع ذلك، فإنه ليس من   الحالة:

     

     

وأنا أفهم منطق، وأخيرا لابد من تنفيذ القسم، ولكن   بطريقة ما أشعر بعدم الارتياح حول هذا الموضوع. دعونا نرى ما # C يفعل في هذه الحالة:

class ReturnFromFinally  
{  
 public static int a()  
 {  
  try {  
          return 1;  
  }  
  catch (System.Exception e) {}  
  finally   
  {   
   return 2;  
  }  
 }  

 public static void Main(string[] args)  
 {  
  System.Console.WriteLine(a());  
 }  
}  
     

 خطأ CS0157 تحكم لا يمكن ترك جثة أخيرا فقرة

     

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

     

وبيثون:

def a():  
 try:  
  return 1  
 finally:  
  return 2  
print a()  
     

     

وجافا سكريبت:

<script>  
function ReturnFromFinally()  
{  
 try  
 {  
  return 1;  
 }  
 catch (e)  
 {  
 }  
 finally  
 {  
  return 2;  
 }  
}  
</script>  
<a onclick="alert(ReturnFromFinally());">Click here</a>  
     

     

وليس هناك بند في النهاية في C ++ و PHP، لذلك لا أستطيع أن محاولة الخروج من الماضي   لغتين لدي مترجم / مترجم لل.

     أظهر

وتجربتنا قليلا لطيف، أن C # لديه اجمل نهج   لهذه المشكلة، ولكن فوجئت جدا للتعلم، أن جميع   لغات أخرى التعامل مع المشكلة بنفس الطريقة.

العودة من النهاية هي لا فكرة جيدة.أعلم أن C# يمنع على وجه التحديد القيام بذلك.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top