2016-06-09 113 views
1

我想在Python 3中利用新類型註釋功能創建抽象通用基類,並支持泛型。Python類型錯誤:'通用'對象不是可下標的 - 如何聲明和實例化通用基類

我有一個基類並將其定義爲這樣一個派生類:

from abc import ABCMeta, abstractmethod 
from typing import TypeVar, Generic, Iterator, List, Dict, Optional 

_T = TypeVar('_T') 

class FileReader(Generic(_T)): 
    __metaclass__ = ABCMeta 
    def __init__(self, filename: str, verbose: bool = False): 
     pass 

_X = TypeVar('_X') 

class EmploymentHistoryFileReader(FileReader[_X]): 
    def __init__(self, filename: str, verbose: bool = False): 
     FileReader.__init__(filename=filename, verbose=verbose) 

當我嘗試實例類型的對象EmploymentHistoryFileReader [EmploymentHistoryFileRow]我得到:

File "/Users/simon.hughes/GitHub/analytics-py-careerpathing/careerpathing/data/employment_history_file_reader.py", line 38, in <module> 
class EmploymentHistoryFileReader(FileReader[_X]): 
TypeError: 'Generic' object is not subscriptable 

我有嘗試了很多不同的東西,例如在聲明子類或實例化子類時指定通用參數的值,並且它們都導致相同的錯誤消息。核心庫有很多正常工作的泛型類型的例子,所以我很困惑,爲什麼我會得到這些錯誤。

+0

除了括號修正,你不應該設置'__metaclass__ = ABCMeta'。因爲1)他們改變了在Python 3中指定元類的語法,2)你沒有任何抽象方法,3)你的類將繼承'Generic [_T ]'。 – user2357112

+0

我確實有抽象方法,爲了簡潔,我省略了它們,因爲它們不會影響問題。我想知道是否需要它,因爲我看到通用類是ABC,所以我會刪除它。 – Simon

回答

2

這條線:

class FileReader(Generic(_T)): 

應該用括號內爲Generic[_T]

class FileReader(Generic[_T]): 

Generic是通用的,像任何其他通用的ABC,你在括號中指定其類型參數。

+0

謝謝,我不敢相信我錯過了,我一直盯着那個代碼太久了。只要它能讓我回答就會回答。 – Simon