2013-02-22 38 views
38

Tôi có một tập lệnh trong đó người dùng được nhắc nhập tên tệp (của tệp sẽ được mở) và nếu tệp không tồn tại trong thư mục hiện tại, người dùng sẽ được nhắc lại. Dưới đây là phiên bản ngắn:"Mở()" của Python ném các lỗi khác nhau cho "tệp không tìm thấy" - cách xử lý cả hai ngoại lệ?

file = input("Type filename: ") 

... 
try: 
    fileContent = open(filename, "r") 
    ... 
except FileNotFoundError: 
    ... 

Khi tôi kiểm tra kịch bản của tôi trên hệ điều hành MacOS X của tôi bằng Python 3.3x nó làm việc hoàn toàn tốt đẹp khi tôi gõ tên tập tin sai về mục đích (nó thực thi bộ dưới "mong đợi").

Tuy nhiên, khi tôi muốn chạy mã của mình trên máy tính Windows bằng Python 3.2x, tôi gặp lỗi nói rằng "FileNotFoundError" không được xác định. Vì vậy, Python 3.2 trên Windows nghĩ rằng "FileNotFoundError" là một biến và các chương trình thoát với một lỗi.

Tôi đã tìm ra rằng Python 3.2 trên Windows sẽ ném "IOError" nếu tên tệp đầu vào không hợp lệ. Tôi đã thử nghiệm nó trên máy Linux của tôi trong Python 2.7, và nó cũng là một IOError.

Vấn đề của tôi là bây giờ, rằng mã với

except "FileNotFoundError": 

sẽ không chạy trên Windows của Python 3.2, nhưng nếu tôi thay đổi nó để

except "IOError": 

nó sẽ không hoạt động trên máy Mac của tôi nữa không.

Tôi làm cách nào để khắc phục sự cố? Cách duy nhất tôi có thể nghĩ đến là sử dụng chỉ except mà tôi thường không muốn.

+6

Điều này không phải do Mac/Windows, đó là phiên bản * của Python. Tôi cũng sẽ điều tra 3.2/3.3 trên OS X (và 3.3 trên Windows), tham khảo nhật ký thay đổi và sau đó sửa lại câu hỏi/tiêu đề nếu thích hợp. –

Trả lời

56

Trong 3.3, IOError became an alias for OSError, và FileNotFoundError là một lớp con của OSError. Vì vậy, bạn có thể thử

except (OSError, IOError) as e: 
    ... 

này sẽ quăng một mẻ lưới khá rộng, và bạn không thể giả định rằng ngoại lệ là "không tìm thấy file" mà không kiểm tra e.errno, nhưng nó có thể bao gồm trường hợp sử dụng của bạn.

PEP 3151 thảo luận về lý do thay đổi chi tiết.

2

bạn có thể bắt 2 lỗi cùng lúc

except (FileNotFoundError, IOError):

Tôi đã không nhận ra đó là những gì bạn đã yêu cầu. Tôi hy vọng có một giải pháp hùng hồn hơn sau đó tự kiểm tra

try: 
    error_to_catch = FileNotFoundError 
except NameError: 
    error_to_catch = IOError 

except error_to_catch

cwallenpoole thực hiện điều này có điều kiện hơn hùng hồn trong câu trả lời của ông (error_to_catch = getattr(__builtins__,'FileNotFoundError', IOError))

+2

Thao tác này có hoạt động ở đâu không - * Tôi gặp lỗi nói rằng "FileNotFoundError" không được xác định. Vì vậy, Python 3.2 trên Windows nghĩ rằng "FileNotFoundError" là một biến và các chương trình thoát với một lỗi * -? –

+0

@pst thú vị xin lỗi đã không xem xét nó – dm03514

7

này đập vào mắt tôi là tốt hơn so với một đơn giản except:, nhưng tôi không chắc chắn nếu nó là giải pháp tốt nhất:

error_to_catch = getattr(__builtins__,'FileNotFoundError', IOError) 

try: 
    f = open('.....') 
except error_to_catch: 
    print('!') 
+0

Trong tin tức khác 'ngoại trừ:' theo sau là một dấu phẩy là đúng ngữ pháp, nhưng vẫn có vẻ rất kỳ quặc. – cwallenpoole

+0

Đó cũng là một giải pháp rất hay. Dài hơn một chút so với 'except (IOError, OSError):' nhưng do đó cụ thể hơn –

3

Vì vậy, để chính xác bắt chỉ khi một tập tin không được tìm thấy, tôi làm:

import errno 
try: 
    open(filename, 'r') 
except (OSError, IOError) as e: # FileNotFoundError does not exist on Python < 3.3 
    if getattr(e, 'errno', 0) == errno.ENOENT: 
     ... # file not found 
    raise 
Các vấn đề liên quan