【问题标题】:Pycharm type hinting with abstract methods带有抽象方法的 Pycharm 类型提示
【发布时间】:2018-02-17 07:17:21
【问题描述】:
from abc import ABCMeta, abstractmethod

class Shape(object):

    _metaclass_ = ABCMeta

    @abstractmethod
    def calculate_area(self):
        """ Returns the area of the shape
        :return str: A string of the area. """
        pass

    def print_area(self):
        area = self.calculate_area()
        print("Area is " + area)

在此示例中,所有形状计算其面积的方式都不同,但所有子类都有一个打印当前面积的通用方法。 Pycharm 在最后一行抱怨area,说它的类型是None 而不是TypeVar('AnyStr', str, unicode)。这是有道理的,因为calculate_area 什么也不返回。另一方面,calculate_area 是一个抽象方法,所以它不会在Shape 下直接调用,它会被子类以不同的方式实现。显然 calculate_area 的返回类型不能在 Child 类上强制执行,但是 PyCharm 不应该推迟告诉我类型错误,因为 calculate_area 是抽象的吗?

我想知道是 Pycharm 有问题,还是我有问题,这不是实现这个抽象类的方法,我应该尝试不同的方法?

这是一个最小的例子。我正在处理的代码在调用许多抽象方法的抽象类中有一个主要(非抽象)方法。 main 函数在所有子类中通用,但抽象方法需要为子类的特定目的而被覆盖。结果,我到处都有类型提示错误。

【问题讨论】:

    标签: python python-2.7 pycharm abstract-class


    【解决方案1】:

    问题是您的示例中的calculate_area 隐式返回None。您可以通过返回一个空字符串来“修复它”。这将捕获子类在其calculate_area 中仅返回super(Subclass, self).calculate_area() 的情况:

    class Shape(object):
    
        _metaclass_ = ABCMeta
    
        @abstractmethod
        def calculate_area(self):
            """ Returns the area of the shape
            :return str: A string of the area. """
            return ""
    
        def print_area(self):
            area = self.calculate_area()
            print("Area is " + area)
    

    但是,添加字符串并不是很好的样式。因此,如果您使用format,则问题首先不会存在,因为format 可以处理具有__repr____str__ 方法的任何对象(实际上是任何对象)。因此,即使 calculate_area 返回 None 或者返回数字而不是字符串,它也可以工作:

    class Shape(object):
    
        _metaclass_ = ABCMeta
    
        @abstractmethod
        def calculate_area(self):
            """ Returns the area of the shape
            :return str: A string of the area. """
            pass
    
        def print_area(self):
            area = self.calculate_area()
            print("Area is {}".format(area))
    

    【讨论】:

      猜你喜欢
      • 2020-10-27
      • 1970-01-01
      • 2019-10-06
      • 1970-01-01
      • 2016-01-19
      • 2017-02-08
      • 1970-01-01
      • 1970-01-01
      • 2013-12-26
      相关资源
      最近更新 更多