问题
I'm looking for a way to annotate return type of a factory function.
It returns random child of 'AlgorithmBase'.
class AlgorithmFactory:
_algorithm_types = AlgorithmBase.__subclasses__()
def select_random_algorithm(self) -> AlgorithmBase:
# Select random algorithm
algorithm_class = self._random_generator.choice(AlgorithmFactory._algorithm_types)
algorithm = algorithm_class()
return algorithm
I get error from mypy:
The error I'm getting is:
Cannot instantiate abstract class 'AlgorithmBase' with abstract attributes 'get_constraints' and 'satisfy_constraints'
There is no way to instantiate class 'AlgorithmBase' in this code, how to make mypy understand it?
I want to avoid specifying actual sub-classes with 'Union' in return type. Any suggestions?
回答1:
The problem here wasn't return type, but '_algorithm_types'. mypy has no way to understand what type it is, so it assumed that it is like return type and got error.
The following code fix the issue:
_algorithm_types: List[Type[AlgorithmBase]] = AlgorithmBase.__subclasses__()
回答2:
As far as I can tell this should work, but it seems like one or more of your AlgorithmBase subclasses doesn't implement these two abstract methods.
Running MyPy for
import abc
class AlgorithmBase(abc.ABC):
@abc.abstractmethod
def get_constraints(self):
raise NotImplementedError
@abc.abstractmethod
def satisfy_constraints(self):
raise NotImplementedError
class SomeAlgorithm(AlgorithmBase):
pass
class AlgorithmFactory:
def get(self) -> AlgorithmBase:
algorithm = SomeAlgorithm()
return algorithm
yields the same error you get, and it runs without any error once the methods are implemented.
import abc
class AlgorithmBase(abc.ABC):
@abc.abstractmethod
def get_constraints(self):
raise NotImplementedError
@abc.abstractmethod
def satisfy_constraints(self):
raise NotImplementedError
class SomeAlgorithm(AlgorithmBase):
def get_constraints(self):
pass
def satisfy_constraints(self):
pass
class AlgorithmFactory:
def get(self) -> AlgorithmBase:
algorithm = SomeAlgorithm()
return algorithm
来源:https://stackoverflow.com/questions/62283480/how-to-add-hint-to-a-factory-method