2012-06-22 12 views
53

Đây là một số mã hoạt động đặc biệt. Đây là một phiên bản đơn giản của hành vi mà tôi đã viết. Điều này vẫn sẽ chứng minh hành vi kỳ lạ và tôi đã có một số câu hỏi cụ thể về lý do tại sao điều này xảy ra.Hành vi lạ-ngoại trừ-khác-Cuối cùng với báo cáo Trả lại

Tôi đang sử dụng Python 2.6.6 trên Windows 7.

def demo1(): 
    try: 
     raise RuntimeError,"To Force Issue" 
    except: 
     return 1 
    else: 
     return 2 
    finally: 
     return 3 

def demo2(): 
    try: 
     try: 
      raise RuntimeError,"To Force Issue" 
     except: 
      return 1 
     else: 
      return 2 
     finally: 
      return 3 
    except: 
     print 4 
    else: 
     print 5 
    finally: 
     print 6 

if __name__ == "__main__": 
    print "*** DEMO ONE ***" 
    print demo1() 
    print "****************" 
    print 
    print "*** DEMO TWO ***" 
    print demo2() 
    print "****************" 

Khi bạn chạy kịch bản này, nó sẽ in:

*** DEMO ONE *** 
3 
**************** 

*** DEMO TWO *** 
6 
3 
**************** 

Tại sao bản demo một trở về 3 thay vì 1? Tại sao bản trình diễn hai in 6 thay vì in 6 w/4 hoặc 5?

Cảm ơn sự giúp đỡ của bạn.

Trả lời

80

Vì báo cáo finally được đảm bảo được thực hiện (tốt, giả sử không bị cúp điện hoặc bất kỳ điều gì ngoài tầm kiểm soát của Python). Điều này có nghĩa là trước khi hàm có thể trả về, nó phải chạy khối cuối cùng, trả về một giá trị khác.

Các Python docs nhà nước:

Khi quay trở lại, phá vỡ hoặc tiếp tục tuyên bố được thực hiện trong bộ ứng dụng thử một thử ... cuối cùng tuyên bố, mệnh đề cuối cùng cũng được thực hiện 'trên đường ra.' Một tuyên bố tiếp tục là bất hợp pháp trong điều khoản cuối cùng. (Lý do là một vấn đề với việc thực hiện hiện tại - hạn chế này có thể được dỡ bỏ trong tương lai).

Điều này có nghĩa là khi bạn cố gắng trả lại, khối finally được gọi, trả lại giá trị của nó, thay vì giá trị bạn đã có.

+1

tại sao không in 5 trong ví dụ thứ hai? điều này vẫn chưa được giải thích rõ ràng. trả lại một trong những cũng được trả lời nhưng tại sao doesnt 5 trong ví dụ thứ hai in –

+4

oh tôi nghĩ rằng tôi figured nó ra sự trở lại trong thử ban đầu gây ra nó nhảy ngay lập tức để bên ngoài cuối cùng –

+2

Chính xác, vì 'cuối cùng' khối ** luôn luôn ** chạy. –

1

Trình tự thực hiện là: khối

  1. thử tất cả hoàn thành bình thường -> khối finally -> chức năng kết thúc
  2. khối try chạy và nhận được vào ngoại lệ A -> khối finally -> chức năng kết thúc
  3. thử khối tạo giá trị trả về và trả về cuộc gọi -> cuối cùng là khối -> giá trị trả về bật lên -> chức năng kết thúc

Vì vậy, bất kỳ trở lại trong khối cuối cùng sẽ kết thúc các bước trước.

+0

Bạn có thể sử dụng định dạng danh sách cho câu trả lời của mình. – gsamaras