2016-03-29 37 views
16

我目前正致力於創建一個python線性代數模塊,以獲得有趣的語言練習。我最近嘗試類型註釋添加到模塊,因爲這樣的:未在類型註釋中定義的名稱

class Vector: 
    # Various irrelevant implementation details 
    def __add__(self, other: Vector) -> Vector: 
     # More implementation details.... 

然而,當我嘗試導入此,它吐出NameError: Name 'Vector' is not defined。我承認這個問題已經以here的形式得到解答,但似乎並沒有完全爲我的情況提供答案。

我想知道些什麼:

  • 我在這個文件的字面定義的類。爲什麼說這個名字沒有定義?
  • 如何定義Vector以使其可用於註釋(作爲type)?
+0

請保留您的帖子限於每個帖子** 1個問題。在這裏你有兩個截然不同的問題,一個是關於你的循環依賴(類的方法取決於類創建之前的類),以及類型和類之間的區別。後者是重複的。 –

+0

請參見[Class vs.輸入Python](https://stackoverflow.com/q/35958961),以查看我已從您的帖子中刪除的部分問題。 –

+0

對不起。我認爲類型問題與手頭的問題有關。 – BHustus

回答

21

您有前向聲明;功能(將被綁定爲方法)之前該類是,因此名稱Vector尚不存在。只有當所有的類體已經被執行時,Python才能創建class對象並將名稱Vector綁定到它。

只需使用一個字符串名稱來代替:

class Vector: 
    # Various irrelevant implementation details 
    def __add__(self, other: 'Vector') -> 'Vector': 
     # More implementation details.... 

這不會影響你的IDE是如何看待的聲明;一旦整個模塊被加載,字符串就會被查找,並且在當前上下文中被解析爲有效的Python表達式。由於類Vector在整個模塊加載後都存在,字符串'Vector'可以正確轉換爲類對象。

另請specification on forward references

當一種暗示包含尚未定義的名稱,該定義可以表示爲一個字符串,以後解決。

[...]

的字符串文字應包含一個有效的Python表達式[...],它應該沒有錯誤評估一旦模塊已經滿載。

+0

謝謝。我在鏈接問題中看到了字符串答案,但是拋棄了我的是,它突出顯示了「other:Vector」與類顏色,以及' - > Vector'沒有,因此當我評論後者時Vector我從來沒有假設I前者需要這樣做。感謝您的澄清。 – BHustus

1

如果您使用Python 3.7及以上版本。看看Postponed evaluation of annotations

因爲Python 3.7,它會被允許,只需添加:

from __future__ import annotations 

而且也注意到,

它將成爲在Python 4.0的默認設置。

+1

這很有意思。因爲它適用於所有3.x版本(或者至少比'import annotations'解決方案更多的3.x版本),但我仍然很高興你在這裏發佈這個答案。 – BHustus