2015-03-30 20 views
11

Tôi luôn bị nhầm lẫn về việc liệu một hàm sẽ tăng IOError hoặc OSError (hoặc cả hai?). Quy tắc nguyên tắc đằng sau các loại ngoại lệ này là gì, sự khác biệt giữa chúng là gì và khi nào được nêu ra?Sự khác nhau giữa IOError và OSError?

Tôi đã nghĩ OSError ban đầu dành cho những thứ như từ chối quyền, nhưng việc mở tệp mà không có quyền sẽ làm tăng IOError.

+4

* Thay đổi trong phiên bản 3.3: ' EnvironmentError', 'IOError',' WindowsError', 'VMSError',' socket.error', 'select.error' và' mmap.error' đã được hợp nhất thành 'OSError'. * Ví dụ chỉ cần ném 'OSError' và quên đi' IOError'. –

+0

@MartijnPieters Cảm ơn, tôi đã thêm thẻ Python 2. Chỉ cần ném OSError âm thanh tốt với tôi, nhưng tôi luôn luôn gặp khó khăn để biết khi nào một chức năng như 'shutil.copyfile()' hoặc 'os.access()' sẽ tăng IOError hoặc OSError (luôn luôn phải nhìn nó lên) –

+2

Ngoài ra, hãy xem https://www.python.org/dev/peps/pep-3151/ để biết thông tin cơ bản về điều này, nó sẽ giúp đưa hai ngoại lệ này vào quan điểm. –

Trả lời

21

Có rất ít sự khác biệt giữa hai loại. Trong thực tế, ngay cả các nhà phát triển Python cốt lõi cũng đồng ý rằng không có sự khác biệt thực sự và loại bỏ IOError bằng Python 3 (bây giờ nó là bí danh cho OSError). Xem PEP 3151 - Reworking the OS and IO exception hierarchy:

While some of these distinctions can be explained by implementation considerations, they are often not very logical at a higher level. The line separating OSError and IOError , for example, is often blurry. Consider the following:

>>> os.remove("fff") 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
OSError: [Errno 2] No such file or directory: 'fff' 
>>> open("fff") 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
IOError: [Errno 2] No such file or directory: 'fff' 

Vâng, đó là hai loại ngoại lệ khác nhau với thông điệp chính xác cùng một lỗi.

Đối với mã của riêng bạn, hãy dính vào ném OSError. Đối với chức năng hiện có, kiểm tra tài liệu (cần chi tiết những gì bạn cần để bắt), nhưng bạn có thể một cách an toàn bắt cả hai:

try: 
    # ... 
except (IOError, OSError): 
    # handle error 

Trích dẫn các PEP lại:

In fact, it is hard to think of any situation where OSError should be caught but not IOError , or the reverse.

+0

hay: 'trừ EnvironmentError:' (mà sau đó lớp cơ sở của WindowsError, mmap.error, shutil.Error, vv quá trên PY2) – kxr

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