2009-10-16 36 views
6

Gần đây tôi đã tình cờ gặp một sự mâu thuẫn dường như trong cách xử lý của Python với các mệnh đề khác trong các câu lệnh ghép khác nhau. Kể từ khi Python được thiết kế rất tốt, tôi chắc chắn rằng có một lời giải thích tốt, nhưng tôi không thể nghĩ về nó.Tại sao người khác lại hành xử khác trong các câu lệnh trong/khi trái ngược với câu lệnh if/try?

xem xét như sau:

if condition: 
    do_something() 
else: 
    do_something_else() 

Ở đây, do_something_else() chỉ thực hiện nếu condition là sai, như mong đợi.

Tương tự, trong

try: 
    do_something() 
except someException: 
    pass: 
else: 
    do_something_else() 
finally: 
    cleanup() 

do_something_else() chỉ được thực hiện nếu không có ngoại lệ xảy ra.

Nhưng trong hoặc trong khi vòng lặp, một mệnh đề khác luôn được thực hiện, cho dù nội dung của for/while block đã được thực thi hay chưa.

for i in some_iterator: 
    print(i) 
else: 
    print("Iterator is empty!") 

sẽ luôn in "Iterator trống!", Cho dù tôi nói some_iterator = [] hoặc some_iterator = [1,2,3]. Hành vi tương tự trong các mệnh đề while-else. Dường như với tôi rằng else hoạt động giống như finally trong những trường hợp này. Tôi đang nhìn gì?

+0

Tôi ngạc nhiên khi Python cho phép cú pháp. Trong hầu hết các ngôn ngữ khác -else bị hạn chế chỉ được sử dụng với if- hoặc switch-statement. Các vòng lặp và các câu lệnh thử có thể kiểm soát luồng, nhưng chúng không có điều kiện giống như một câu lệnh if, do đó, -else không có chỗ trong chúng. – shuckster

+2

Đối với những gì nó có giá trị, đã có một cuộc thảo luận gần đây dài của for/else, et al, trên danh sách python-ideas, tóm tắt ở đây: http://article.gmane.org/gmane.comp.python.ideas/6131 /. Bản thân Guido thừa nhận có suy nghĩ thứ hai về nó: http://article.gmane.org/gmane.comp.python.ideas/6133/ –

+0

Cảm ơn các liên kết này! –

Trả lời

5

Vâng, nó phụ thuộc vào cách bạn nhìn thấy nó. Bạn có thể nhìn vào elses như thế này (tha la hét, cách duy nhất của mình để làm nhấn mạnh trong code):

if condition: 
    do_something() 
IF THE PREVIOUS CONDITION WAS FALSE: 
    do_something_else() 

Bây giờ, có một sự tương đồng rõ ràng giữa if/else và thử/trừ/khác, nếu bạn thấy câu lệnh khác là câu lệnh khác với câu lệnh ngoại trừ. Như thế này.

try: 
    do_something() 
IF THERE WAS AN EXCEPTION: 
    pass: 
IF THE PREVIOUS CONDITION WAS FALSE: 
    do_something_else() 
finally: 
    cleanup() 

Cùng đi cho khác/cho:

IF some_iterator IS NOT EMPTY: 
    i = next(some_iterator) 
    print(i) 
IF THE PREVIOUS CONDITION WAS FALSE: 
    print("Iterator is empty!") 

Vì vậy, ở đây chúng tôi thấy rằng các khác trong một số cách cơ bản làm công việc giống hệt nhau trong cả ba trường hợp.

Nhưng bạn cũng có thể thấy khác theo cách này:

try: 
    do_something() 
except someException: 
    pass: 
IF NO EXCEPTION: 
    do_something_else() 
finally: 
    cleanup() 

Và sau đó nó không giống nhau nữa, nhưng khác vì một loại "nếu không có gì khác".Bạn có thể xem cho/khác trong cùng một cách:

for i in some_iterator: 
    print(i) 
IF NO MORE ITERATING: 
    print("Iterator is empty!") 

Nhưng sau đó một lần nữa, xem xét elif, sau đó theo cách này nhìn thấy nó hoạt động cho if/else cũng như:

if condition: 
    do_something() 
elif otherconditaion: 
    do_anotherthing() 
IF NO CONDITION WAS TRUE: 
    do_something_else() 

Cách mà bạn muốn nhìn vào người khác là tùy thuộc vào bạn, nhưng theo cả hai cách xem, người khác lại có điểm tương đồng trong cả ba trường hợp.

+0

Cảm ơn. Điều này có ý nghĩa và trả lời câu hỏi của tôi. –

13

Các for else xây dựng thực thi mệnh đề else nếu không có tuyên bố break được thực hiện cho các vòng lặp, as described here Ví dụ, mệnh đề else này không bao giờ được đánh giá

for i in range(1,10): 
    if i % 5 == 0: 
     print i 
     break 
else: 
    print "nothing divisible by 5" 
+0

Phải, do đó, một tuyên bố cho/trong khi khác chỉ có ý nghĩa nếu có một tuyên bố phá vỡ ở đâu đó. –

4

Vâng, như Eli đã đề cập, các khoản khác chỉ được thực hiện nếu bạn không phá vỡ. Việc này khiến bạn không thể triển khai mã như thế này:

for i in range(1,10): 
    if i % 5 == 0: 
     print i 
     break 
if i % 5 != 0: 
    print "nothing divisible by 5" 

Tương đương với điều này, nhưng tiện dụng hơn nếu kiểm tra nhiều điều kiện hoặc kết hợp điều kiện khác nhau).

Các vấn đề liên quan