2017-12-03 54 views
3

我讀了很多關於泛型類的內容,雖然這些類很酷,但有時候我只需要一個泛型函數。這是我寫的一個小的:Python中泛型函數的最佳實踐

def _matrix_map(self, mapper): 
    """returns the matrix applying the mapper funcfunc""" 
    return {key: mapper(value) for key, value in self._matrix.items()} 

這是怎麼被註釋的類型。在與通用支持靜態類型語言,我會寫這樣的事情

private Dictionary<KeyType, ValueType> matrix; 
private Dictionary<KeyType, T> matrix_map<T>(Func<ValueType, T>) 

所以,我想我會寫這樣的:

T = TypeVar('T') 
def _matrix_map(self, mapper: Callable[[Tile], T]) -> Dict[Coordinate, T]: 

我得到了它與mypy傳遞像這樣,但pylint討厭這個。

第一行:

C0103:Invalid class attribute name "T" 

而且在第二行:

E0602:Undefined variable 'T' 

所以我覺得我做錯了什麼,我可以改變的變量名(ttttyp?),但這並不能解決第二個問題。我不能成爲第一個想要(靜態類型)泛型函數的人,但我無法在任何地方找到任何好的資源。任何建議?

+0

你進口的打字員嗎? –

+0

@SamCraig是的,我做了,問題不是它找不到類型,而是它找不到T,我在前一行中聲明的變量。 – McKay

回答

1

我猜你寫的代碼看起來大致是這樣嗎?

class Matrix: 
    T = TypeVar('T') 

    def _matrix_map(self, mapper: Callable[[Tile], T]) -> Dict[Coordinate, T]: 
     # ...snip... 

實際上,有沒有問題,這個在運行時mypy /沒有問題,但似乎pylint的不幸福跟你把那個「T」類定義的範圍內。你可以做什麼來滿足pylint的是不是這樣做:

T = TypeVar('T') 

class Matrix: 
    def _matrix_map(self, mapper: Callable[[Tile], T]) -> Dict[Coordinate, T]: 
     # ...snip... 

這是完全等同於以前的代碼片段,也將滿足pylint的。 (作爲一個相切點,我認爲pylint對前者不滿意的事實實際上是一個錯誤。但公平地說,對於類型提示的最佳實踐並沒有真正的建立風格指南然而,將一個typevar放在嵌套的作用域內是一個不常見的用例,所以我想我不能指責他們不考慮這種情況。)

唯一的缺點是在外部有TypeVar看起來似乎含糊不清/看起來會污染全局命名空間。例如,您可以通過將其重命名爲_T等來部分緩解此問題,以表明它是私密的。當你需要另一個泛型類或函數時,你也可以重用這個類型變量,這也應該有助於減少名稱空間的污染。

有關使用泛型與Python類型提示的更多信息,請參閱http://mypy.readthedocs.io/en/stable/generics.html