【问题标题】:How to add hint to a factory method?如何向工厂方法添加提示?
【发布时间】:2020-06-09 13:13:51
【问题描述】:

我正在寻找一种方法来注释工厂函数的返回类型。

它返回“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

我从 mypy 收到错误:

我得到的错误是:

Cannot instantiate abstract class 'AlgorithmBase' with abstract attributes 'get_constraints' and 'satisfy_constraints'

这段代码中没有办法实例化'AlgorithmBase'类,如何让mypy理解?

我想避免在返回类型中指定带有“Union”的实际子类。有什么建议吗?

【问题讨论】:

    标签: python python-3.x mypy


    【解决方案1】:

    这里的问题不是返回类型,而是“_algorithm_types”。 mypy 无法理解它是什么类型,所以它假设它像返回类型并得到错误。

    以下代码解决了这个问题:

    _algorithm_types: List[Type[AlgorithmBase]] = AlgorithmBase.__subclasses__()
    

    【讨论】:

      【解决方案2】:

      据我所知,这应该可行,但您的一个或多个 AlgorithmBase 子类似乎没有实现这两个抽象方法。

      运行 MyPy
      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
      

      产生与您得到的相同的错误,并且一旦实现方法,它就会运行而不会出现任何错误。

      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
      

      【讨论】:

      • 这是正确的。然而错误出现在这一行:algorithm = algorithm_class()。它从_algorithm_types 中选择随机类并给出错误,因为它不知道algorithm 的类型。根据返回类型,它假设它也可能是AlgorithmBase并给出错误,因为这个类是抽象的。在变量上添加类型解决了这个问题,这意味着有时需要为复杂类型添加提示,而不仅仅是函数
      • 在你的情况下,它“知道”算法的确切类型:SomeAlgorithm 因为你直接分配它,所以这里没有你说的错误
      • 另外,如果问题出在AlgorithmBase 的实现上,则错误消息中会提到该具体实现而不是抽象类
      猜你喜欢
      • 2010-11-23
      • 1970-01-01
      • 1970-01-01
      • 2023-04-01
      • 1970-01-01
      • 2019-08-14
      • 2023-04-04
      • 1970-01-01
      • 2011-10-30
      相关资源
      最近更新 更多