2016-07-25 91 views
12

Python的新type hinting功能類型暗示允許我們鍵入暗示函數返回None ...一個函數永遠不會返回

def some_func() -> None: 
    pass 

...或離開返回類型不確定,該PEP應該使然導致靜態分析的假設,任何返回類型是可能的:

沒有標註任何功能應被視爲具有最普遍的類型可能

但是,我該如何輸入提示函數永遠不會返回?例如,鍵入提示這兩個函數的返回值的正確方法是什麼?

def loop_forever(): 
    while True: 
     print('This function never returns because it loops forever') 

def always_explode(): 
    raise Exception('This function never returns because it always raises') 

既不指定-> None也不離開返回類型不確定,似乎在這些情況下是正確的。

回答

2

即使「PEP 484 — Type Hints」標準提及問題和答案但沒有人引用其涵蓋您的問題的部分:The NoReturn type

報價:

typing模塊提供一種特殊類型的NoReturn標註,從來沒有正常返回的功能。例如,一個函數,它無條件地引發一個例外:

from typing import NoReturn 

def stop() -> NoReturn: 
    raise RuntimeError('no way') 

該部分還提供了錯誤的用途的例子。儘管它沒有涵蓋無限循環的功能,但在類型理論中它們都同樣滿足從不會返回這個特殊類型表示的含義。

+1

Julian和我大概可以被原諒,因爲在2016年7月我問這個問題時,在PEP 484中沒有注意到'NoReturn'類型,因爲它還沒有存在,直到[幾乎不會添加到PEP一年後](https://github.com/python/peps/commit/881c6bebdb79d3a51dea0a467e81abed410e5570)。不過,是的,這看起來像是現在的正確答案。 –

+0

哇!所以這個更新對於一個三年前的文檔來說是相當新鮮的,但它缺少像[PEP 0](https://www.python.org/dev/peps/)中的「Last Modified」這樣的標題。另外,現在它給了我一個暗示,爲什麼我的IDE不能從'輸入'識別'NoReturn'類型,但在運行時卻沒有真正的問題。 – misanthrope

2

2016年7月,這個問題還沒有答案(現在有NoReturn;請參閱the new accepted answer)。這些都是一些原因:

  • 當一個函數沒有返回,沒有返回值(甚至沒有None)是一類能分到。所以你實際上並沒有試圖註解一個類型;您正在嘗試註釋缺少類型

  • 從Python 3.5版開始,類型暗示PEP只在標準中被採用。此外,PEP只建議看起來像什麼類型的註釋,而故意模糊如何使用它們。所以沒有一個標準告訴我們如何做特別的事情,超越了這些例子。

  • 的PEP具有載明下列一段Acceptable type hints

    註解必須是沒有在函數定義時引發異常評估有效表達式(但請參閱下面的向前引用)。

    註解應保持簡單或靜態分析工具可能無法解釋值。例如,動態計算類型不太可能被理解。 (這是一個故意有些含糊的要求,具體包括和排除可能被添加到作爲擔保的情況下討論這個PEP的未來版本。)

    所以它試圖從做過於創造性的東西阻止你,就像拋出返回類型提示中的異常,以表示函數永不返回。

  • 關於例外,the PEP states the following

    沒有語法列出明確地提出了異常建議。目前,該功能的唯一已知用例是文檔化的,在這種情況下,建議將此信息放入文檔字符串中。

  • 有上type comments的建議,在你有更多的自由,但即使這部分沒有討論如何記錄缺少的類型。

有一兩件事你可以嘗試在一個稍微不同的情況,當你想暗示一個參數或一些「正常」的函數返回值應該是永遠不會返回一個調用。 syntaxCallable[[ArgTypes...] ReturnType],所以您可以省略返回類型,如Callable[[ArgTypes...]]。但是,這不符合推薦的語法,所以嚴格來說這不是一個可接受的類型提示。類型檢查可能會窒息。

結論:你超前於你的時間。這可能會令人失望,但對您來說也有一個優勢:您仍然可以影響如何註釋不返回的函數。也許這將成爲你參與標準化進程的藉口。 :-)

我有兩個建議。

  1. 允許在Callable提示允許的任何類型向前暗示省略返回類型。這將導致以下語法:

    always_explode: Callable[[]] 
    def always_explode(): 
        raise Exception('This function never returns because it always raises') 
    
  2. 介紹一個bottom type like in Haskell

    def always_explode() -> ⊥: 
        raise Exception('This function never returns because it always raises') 
    

這兩個建議都可以結合起來。

相關問題