2013-04-18 62 views
4

Python在編譯時不檢查類型,因爲它不能,至少在某些情況下不能。但是有沒有人想出一種基於用戶額外註釋的編譯時類型檢查機制?像pylint這樣的作者使用額外的保證?我想的是這樣的:Python編譯時類型檢查

#guarantee(argument=int, return_type=int) 
def f(x): 
    return x + 3 

#guarantee(argument=int, return_type=str) 
def g(x): 
    return "%d times" % x 

y = f(6) 

# works, z = "9 times" 
z = g(y) 
# error 
a = f(z) 

這將檢查每一個解釋函數上述意見,實現f(x)只應該接受int但Z與從g(x)所以這是一個str。有沒有什麼產品可以做類似的事情?

+1

我的理解是PyPy確實有點像這樣,但通常人們不會嘗試去Python Python,他們只是使用嚴格類型的語言。另外,Python中的「編譯時」實際上並不存在。您可以進行靜態或動態代碼分析,並且可以將pyc轉換爲編譯,但是在基本級別上,任意代碼可以在運行時更改有關係統的任何內容。 –

回答

2

PEP 3107最近完成了(最近在去年的某個時候),它引入了變量和函數的註釋。不幸的是(正如你可以從pep數中看到的),這隻適用於Python 3.x,所以你編寫的任何檢查器(甚至是代碼)都只能使用Python 3(這真的不是壞事)。

你提到pylint,所以我假設你實際上並不想在編譯時運行檢查,而是在編譯後檢查。這將是一個很好的工具,可以在code-quality mailing list上進行討論。

+0

這正是我所期待的,謝謝! – noisecapella

+0

@noisecapella樂於幫助 –

0

我不知道這是如何比Python中現有的運行時機制有顯着的改進。例如,

def f(x): 
    if not isinstance(x, int): 
     raise TypeError("Expected integer") 
    return x + 3 

def g(x): 
    return "%d times" % x 

# Works. 
y = f(6) 
z = g(y) 
# Fails, raises TypeError. 
a = f(z) 

換一種方式,沒有標註每一個函數和Python中的每個對象的每一個方法,這將是困難的靜態判斷到底是什麼或者fg的返回類型。我懷疑沿着這些線路的任何靜態檢查器都沒有任何價值。

即使您向函數添加了返回類型描述符,這真的是一個保證嗎?它看起來更像是可能無法與代碼一起更新的文檔,從而導致後來錯誤假設導致更加隱蔽的錯誤。

+2

那麼當對待它時(像'__str__','__nonzero__'等等),對象的行爲如何呢? Python處於鴨子式的基本水平;任何強加靜態類型的嘗試都會失敗或破壞語言。 –

+0

標籤'靜態分析'意味着這並不意味着在運行時強加。 –

+0

我知道這是隱含的問題,但我認爲提供正確的,習慣性的答案更重要。 –

1

我想你的遺漏關鍵字是decorator

您可以編寫自己的裝飾做的東西,如:

@check(bar=int) 
foo(bar): 
    pass 

您可以看到一個示例實現here。雖然這對於編譯檢查當然是無效的,因爲它是在運行時完成的。

+0

是的,我實現了一次這樣的事情。在實現這些裝飾器時,一個小於酷的問題是讓IDE知道你做了什麼,所以代碼建議可能會搞砸 - 不知道你是否在你的例子中做了它。編輯︰neah,這就是問題,如果你只是通過* args和** kwargs,代碼建議會在翻譯中丟失:P –