2012-08-30 41 views
5

函數註釋似乎重複已經在Python中找到的行爲。不僅如此,他們採取以任何方式不是強制的,因此它們可用於下列任何記錄的PEP 3107含義:爲什麼函數註釋需要Python中的專用語法?

  • 提供輸入信息
  • 類型檢查
  • 讓我們的IDE顯示函數需要什麼類型的,並返回
  • 函數重載/通用功能
  • 外語橋樑
  • Adaptati上
  • 謂詞邏輯功能
  • 數據庫的查詢映射
  • RPC參數編組
  • 其他信息
  • 文檔爲參數和返回值

或者甚至完全不同的東西。

在某種程度上,功能註解讓我想起一個老笑話的Python's humour collection

事實上,巨蟒已經支持塊分隔符:

> 
>  if foo: #{ 
>   foo1(); 
>   foo2(); 
>   foo3(); 
>  #} 

def foo(a: 'x', b: 5 + 6, c: list) -> max(2, 9): 
    ... 

對於:

# a: 'x', b: 5 + 6, c: list 
def foo(a, b, c): #-> max(2, 9): 
    ... 

可能有人會認爲功能註釋是必要的,因爲不同的意見,他們可以從代碼中訪問,如:

>>> def spam(a: 'eggs') -> 'ni!': 
...  pass 
... 
>>> spam.__annotations__ 
{'a': 'eggs', 'return': 'ni!'} 

雖然這種行爲可以很容易地與裝飾,等來實現:

def param(**kw): 
    def decorator(func): 
     def wrap(*args): 
      print kw 
      func(*args) 
     return wrap 
    return decorator 

def return_(arg): 
    def decorator(func): 
     def wrap(*args): 
      func(*args) 
      print arg 
     return wrap 
    return decorator 

@param(a='eggs') 
@return_('ni!') 
def spam(a): 
    pass 

spam(None) 

# Output: 
# ------- 
## {'a': 'eggs'} 
## ni! 

Python已經可以做註釋,爲什麼函數註釋需要一個專用的語法?

編輯:我將在我的問題上做一些擴展,因爲它的含義變得有點不清楚。

我特別問功能說明這個問題,而不是裝飾,其中

@decorator 
def spam(): 
    pass 

是短期的

def spam(): 
    pass 
spam = decorator(spam) 

和方法調用,其中

self.method(param) 

短爲

Class.method(self, param) 

有了這兩個速記句法快捷鍵,它們的含義不能不一樣。我不問爲什麼有這樣的捷徑是必要的,當有預先存在的替代品時;這是一個可讀性問題。功能註解是比這兩個快捷方式略有不同,在

def spam() -> int: 
    pass 

def spam() -> 'integer': 
    pass 

可能給人類相同的含義,但不會有電腦相同的含義。即使程序員知道什麼註釋應該定義,沒有關於的定義的商定如何註釋定義它。此外,註釋不影響功能,因此不需要保持一致。

因此,這裏是我的修訂問題:

爲什麼功能註釋需要一個專門的語法時,他們提供訪問現有的語言功能的多變和可能不一致的方式嗎?爲什麼在上沒有強制定義如何使用註釋,何時有什麼可用於(PEP 3107)?

+1

C已經可以做Python的功能了,那麼爲什麼Python需要一個專用的語法呢? –

+1

@MichałGórny「Binary已經可以做C做的事情,那爲什麼C需要一個專用的語法?」你錯過了我的觀點。如果我想用另一種編程語言,我會的。 –

+3

我認爲*你*錯過了我的觀點。你基本上在問:爲什麼添加新的功能時,可以通過定製的少量內容來實現相同的功能? –

回答

6

PEP 3107,你鏈接到似乎提供了一個回答你的問題的「理由」部分:

理由

因爲Python的2.x的系列沒有一個註釋的 的標準方式函數的參數和返回值,各種工具和庫似乎填補了這一空白。一些使用「PEP 318」中引入的裝飾器 ,而其他人則解析函數的文檔字符串, 在那裏尋找註釋。

本PEP旨在提供一種指定此信息的單一標準方式,減少由此之前存在的機制和語法的廣泛變化引起的混淆。

+0

我有點認爲現有的解決方案更好。 – endolith

6

裝飾器語法有什麼意義?它不會讓你做任何事情,你不能這樣做之前:

@staticmethod 
def foo(): 
    pass 

只是

def foo(): 
    pass 
foo = staticmethod(foo) 

但裝飾語法是更好的。

這兩個,這是更好作者:

@param(a='eggs') 
@return_('ni!') 
def spam(a): 
    pass 

def spam(a: 'eggs') -> 'ni!': 
    pass 

意見可能不同,但我認爲第二個是更好的。

相關問題