簡體   English   中英

Python 使用異常進行控制流被認為不好?

[英]Python using exceptions for control flow considered bad?

好的,

過去我已經多次看到這種情況,但最近我的問題在這里 所以,我很好奇為什么會這樣,在 python 中,因為生成器使用異常來指示數據的結尾。

如果這對使用 python 的每個人來說都如此糟糕,為什么該語言將它包含在被認為是基本控制結構中? 對於那些想要閱讀相關 PEP 的人,請訪問這里

因為結束生成器不是一個常見的事件(我知道它總是會發生,但它只會發生一次)。 拋出異常被認為是昂貴的。 如果一個事件有 99% 的成功率和 1% 的失敗率,那么使用 try/except 比檢查是否可以訪問該數據要快得多(請求寬恕比請求許可更容易)。

也有對它的偏見,因為像這樣使用的 try/except 塊可能很難理解。 流控制可能難以遵循,而 if/else 則更直接。 在try /只是意味着你要跟蹤它調用的函數的嘗試內內的語句的流控制(因為它們可能會拋出異常,它可以向上傳播。if / else語句可以在唯一分支機構在點時語句被評估。

有時使用 try/except 是正確的,有時使用 if/else 更有意義。 還有與它們中的每一個相關的性能成本。 考慮:

a = <some dictionary>
if key in a:
    print a[key]

對比

a = <some dictionary>
try:
    print a[key]
except KeyError:
    pass

如果 key 不存在於 a 中,第一個會更快,如果它確實存在,則只會稍微(幾乎不明顯)更慢。 如果鍵確實存在,第二個會更快,但如果它不存在,則會慢得多。 如果 key 幾乎總是存在,則選擇第二個。 否則,第一個效果更好。

編輯:只需添加關於 Python try/except 的一點東西,這對解決可讀性問題之一有很大幫助。

考慮從文件中讀取。

f = None
try:
    f = open(filename, 'r')
    ... do stuff to the file ...
except (IOError, OSError):
    # I can never remember which one of these Python throws...
    ... handle exception ...
finally:
    if f:
        f.close()

現在do stuff to the file任何do stuff to the file都可能引發異常,我們將捕獲它。 通常,出於這個原因,您會嘗試在 try 中保留盡可能少的代碼。 Python 有一個可選的else子句用於 try ,只有當 try 運行完成而沒有遇到異常時才會運行。

f = None
try:
    f = open(filename, 'r')
except (IOError, OSError):
    pass
else:
    ... do stuff to the file ...
finally:
    if f:
        f.close()

在這種情況下,您不會遇到任何可讀性問題,因為 try 中只有一個語句; 它是一個 python 標准庫函數調用,您只捕獲特定的異常。

因為異常是在堆棧上引發的,所以它們適用於某些情況,即您希望使用其他代碼的代碼能夠捕獲異常。 例如,考慮到您想要創建一個迭代器的情況,該迭代器更“手動”地使用另一個迭代器的一部分,擁有一個可以從堆棧的更高層捕獲並插入您自己的邏輯的異常是很有價值的。

一直使用try塊進行流量控制可能會產生如下代碼:

try:
  # stuff
  try:
    if userCondition:
      throw NeedToDoSomethingElseException
    try:
      # stuff
    except NeedToDoSomethingElseException:
      # other stuff
  except NeedToDoSomethingElseException:
    # other stuff
except NeedToDoSomethingElseException:
  # other stuff

撇開性能問題不談,這不是很優雅。 因此,有時使用try非常合適,但並非適用於所有情況。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM