Khi bạn chỉ muốn thực hiện thử - ngoại trừ không xử lý ngoại lệ, làm thế nào để bạn làm điều đó trong Python?
Là cách sau đây đúng để làm điều đó?
try:
shutil.rmtree(path)
except:
pass
try: rob() except: run()
Khi bạn chỉ muốn thực hiện thử - ngoại trừ không xử lý ngoại lệ, làm thế nào để bạn làm điều đó trong Python?
Là cách sau đây đúng để làm điều đó?
try:
shutil.rmtree(path)
except:
pass
try: rob() except: run()
Câu trả lời:
try:
doSomething()
except:
pass
hoặc là
try:
doSomething()
except Exception:
pass
Sự khác biệt là cái đầu tiên cũng sẽ bắt KeyboardInterrupt
, SystemExit
và những thứ như thế, có nguồn gốc trực tiếp từ exceptions.BaseException
, không exceptions.Exception
.
Xem tài liệu để biết chi tiết:
try: shuti.rmtree(...) except: pass
sẽ triệt để khắc phục mọi lỗi (ngay cả khi bạn viết sai chính tả shutil
dẫn đến a NameError
) - ít nhất là làmexcept OSError:
Nói chung, nó được coi là cách thực hành tốt nhất để chỉ bắt những lỗi bạn quan tâm. Trong trường hợp shutil.rmtree
đó có thể là OSError
:
>>> shutil.rmtree("/fake/dir")
Traceback (most recent call last):
[...]
OSError: [Errno 2] No such file or directory: '/fake/dir'
Nếu bạn muốn âm thầm bỏ qua lỗi đó, bạn sẽ làm:
try:
shutil.rmtree(path)
except OSError:
pass
Tại sao? Giả sử bạn (bằng cách nào đó) vô tình truyền vào hàm một số nguyên thay vì một chuỗi, như:
shutil.rmtree(2)
Nó sẽ đưa ra lỗi "TypeError: buộc vào Unicode: cần chuỗi hoặc bộ đệm, int find" - bạn có thể không muốn bỏ qua điều đó, điều này có thể khó gỡ lỗi.
Nếu bạn chắc chắn muốn bỏ qua tất cả các lỗi, hãy nắm bắt Exception
hơn là một except:
tuyên bố trần trụi . Một lần nữa, tại sao?
Không chỉ định một ngoại lệ bắt mọi ngoại lệ, bao gồm SystemExit
ngoại lệ mà ví dụ sys.exit()
sử dụng:
>>> try:
... sys.exit(1)
... except:
... pass
...
>>>
So sánh điều này với những điều sau đây, lối thoát chính xác:
>>> try:
... sys.exit(1)
... except Exception:
... pass
...
shell:~$
Nếu bạn muốn viết mã hành xử tốt hơn bao giờ hết, OSError
ngoại lệ có thể biểu thị các lỗi khác nhau, nhưng trong ví dụ trên chúng tôi chỉ muốn bỏ qua Errno 2
, vì vậy chúng tôi thậm chí có thể cụ thể hơn:
import errno
try:
shutil.rmtree(path)
except OSError as e:
if e.errno != errno.ENOENT:
# ignore "No such file or directory", but re-raise other errors
raise
shutil.rmtree
không phải là ví dụ tốt nhất, bởi vì bạn sẽ chỉ sử dụng ignore_errors=True
cho chức năng đó ..
Khi bạn chỉ muốn thực hiện một thử bắt mà không xử lý ngoại lệ, làm thế nào để bạn làm điều đó trong Python?
Nó phụ thuộc vào những gì bạn có nghĩa là "xử lý."
Nếu bạn muốn bắt nó mà không thực hiện bất kỳ hành động nào, mã bạn đã đăng sẽ hoạt động.
Nếu bạn muốn nói rằng bạn muốn thực hiện hành động đối với một ngoại lệ mà không ngăn chặn ngoại lệ đi lên ngăn xếp, thì bạn muốn một cái gì đó như thế này:
try:
do_something()
except:
handle_exception()
raise #re-raise the exact same exception that was thrown
Đầu tiên tôi trích dẫn câu trả lời của Jack o'Connor từ chủ đề này . Các chủ đề được tham chiếu đã đóng cửa vì vậy tôi viết ở đây:
"Có một cách mới để thực hiện điều này trong Python 3.4:
from contextlib import suppress
with suppress(Exception):
# your code
Đây là cam kết đã thêm nó: http://hg.python.org/cpython/rev/406b47c64480
Và đây là tác giả, Raymond Hettinger, nói về điều này và tất cả các loại độ nóng khác của Python: https://youtu.be/OSGv2VnC0go?t=43m23s
Bổ sung của tôi vào đây là tương đương Python 2.7:
from contextlib import contextmanager
@contextmanager
def ignored(*exceptions):
try:
yield
except exceptions:
pass
Sau đó, bạn sử dụng nó như trong Python 3.4:
with ignored(Exception):
# your code
Để hoàn thiện:
>>> def divide(x, y):
... try:
... result = x / y
... except ZeroDivisionError:
... print("division by zero!")
... else:
... print("result is", result)
... finally:
... print("executing finally clause")
Cũng lưu ý rằng bạn có thể nắm bắt ngoại lệ như thế này:
>>> try:
... this_fails()
... except ZeroDivisionError as err:
... print("Handling run-time error:", err)
... và nêu lại ngoại lệ như thế này:
>>> try:
... raise NameError('HiThere')
... except NameError:
... print('An exception flew by!')
... raise
... ví dụ từ hướng dẫn python .
Làm thế nào để bỏ qua các trường hợp ngoại lệ?
Có một số cách để làm điều này.
Tuy nhiên, sự lựa chọn của ví dụ có một giải pháp đơn giản không bao gồm trường hợp chung.
Thay vì
try:
shutil.rmtree(path)
except:
pass
Làm cái này:
shutil.rmtree(path, ignore_errors=True)
Đây là một đối số cụ thể để shutil.rmtree
. Bạn có thể thấy sự trợ giúp về nó bằng cách thực hiện như sau và bạn cũng sẽ thấy nó cũng có thể cho phép các chức năng về lỗi.
>>> import shutil
>>> help(shutil.rmtree)
Vì điều này chỉ bao gồm trường hợp hẹp của ví dụ, tôi sẽ trình bày thêm cách xử lý vấn đề này nếu những đối số từ khóa đó không tồn tại.
Vì ở trên chỉ bao gồm trường hợp hẹp của ví dụ, tôi sẽ trình bày thêm cách xử lý vấn đề này nếu những đối số từ khóa đó không tồn tại.
Bạn có thể nhập trình suppress
quản lý bối cảnh:
from contextlib import suppress
Nhưng chỉ loại bỏ ngoại lệ cụ thể nhất:
with suppress(FileNotFoundError):
shutil.rmtree(path)
Bạn sẽ âm thầm bỏ qua một FileNotFoundError
:
>>> with suppress(FileNotFoundError):
... shutil.rmtree('bajkjbkdlsjfljsf')
...
>>>
Từ các tài liệu :
Như với bất kỳ cơ chế nào khác loại bỏ hoàn toàn các ngoại lệ, trình quản lý bối cảnh này chỉ nên được sử dụng để khắc phục các lỗi rất cụ thể trong đó việc âm thầm tiếp tục thực hiện chương trình được biết là điều nên làm.
Lưu ý rằng suppress
và FileNotFoundError
chỉ có sẵn trong Python 3.
Nếu bạn muốn mã của mình cũng hoạt động trong Python 2, hãy xem phần tiếp theo:
Khi bạn chỉ muốn thử / ngoại trừ mà không xử lý ngoại lệ, làm thế nào để bạn làm điều đó trong Python?
Là cách sau đây đúng để làm điều đó?
try : shutil.rmtree ( path ) except : pass
Đối với mã tương thích Python 2, pass
là cách chính xác để có một câu lệnh không có op. Nhưng khi bạn làm một trần except:
, đó là giống như làm except BaseException:
trong đó bao gồm GeneratorExit
, KeyboardInterrupt
và SystemExit
, và nói chung, bạn không muốn bắt những điều đó.
Trong thực tế, bạn nên cụ thể trong việc đặt tên ngoại lệ như bạn có thể.
Đây là một phần của hệ thống phân cấp ngoại lệ Python (2) và như bạn có thể thấy, nếu bạn nắm bắt được các Ngoại lệ chung hơn, bạn có thể ẩn các vấn đề bạn không mong đợi:
BaseException
+-- SystemExit
+-- KeyboardInterrupt
+-- GeneratorExit
+-- Exception
+-- StopIteration
+-- StandardError
| +-- BufferError
| +-- ArithmeticError
| | +-- FloatingPointError
| | +-- OverflowError
| | +-- ZeroDivisionError
| +-- AssertionError
| +-- AttributeError
| +-- EnvironmentError
| | +-- IOError
| | +-- OSError
| | +-- WindowsError (Windows)
| | +-- VMSError (VMS)
| +-- EOFError
... and so on
Bạn có thể muốn bắt OSError ở đây và có lẽ ngoại lệ bạn không quan tâm là nếu không có thư mục.
Chúng tôi có thể nhận được số lỗi cụ thể đó từ errno
thư viện và phát lại nếu chúng tôi không có:
import errno
try:
shutil.rmtree(path)
except OSError as error:
if error.errno == errno.ENOENT: # no such file or directory
pass
else: # we had an OSError we didn't expect, so reraise it
raise
Lưu ý, tăng trần làm tăng ngoại lệ ban đầu, đó có thể là những gì bạn muốn trong trường hợp này. Được viết chính xác hơn, vì chúng ta không thực sự cần phải rõ ràng pass
với mã trong xử lý ngoại lệ:
try:
shutil.rmtree(path)
except OSError as error:
if error.errno != errno.ENOENT: # no such file or directory
raise
Khi bạn chỉ muốn thực hiện một thử bắt mà không xử lý ngoại lệ, làm thế nào để bạn làm điều đó trong Python?
Điều này sẽ giúp bạn in ngoại lệ là gì :( tức là thử bắt mà không xử lý ngoại lệ và in ngoại lệ.)
import sys
try:
doSomething()
except:
print "Unexpected error:", sys.exc_info()[0]
try:
doSomething()
except Exception:
pass
else:
stuffDoneIf()
TryClauseSucceeds()
FYI mệnh đề khác có thể đi sau tất cả các ngoại lệ và sẽ chỉ được chạy nếu mã trong lần thử không gây ra ngoại lệ.
else
trong bối cảnh này. Và để thêm rằng finally
sẽ luôn luôn chạy sau bất kỳ (hoặc không có ngoại lệ).
Tôi cần thiết để bỏ qua sai sót trong nhiều lệnh và fuckit đã làm các trick
import fuckit
@fuckit
def helper():
print('before')
1/0
print('after1')
1/0
print('after2')
helper()
Trong Python, chúng tôi xử lý các ngoại lệ tương tự như ngôn ngữ khác, nhưng sự khác biệt là một số khác biệt về cú pháp, ví dụ:
try:
#Your code in which exception can occur
except <here we can put in a particular exception name>:
# We can call that exception here also, like ZeroDivisionError()
# now your code
# We can put in a finally block also
finally:
# Your code...
Tôi thường chỉ làm:
try:
doSomething()
except:
_ = ""
_ = ""
bằng pass
.
shutil.rmtree(path, ignore_errors=True)
. Điều này sẽ không áp dụng cho hầu hết các chức năng, tuy nhiên.