Python 2.7类型提示用于具有存根的子类

时间:2018-05-09 14:08:29

标签: python-2.7 pycharm type-hinting

您可以在每个https://www.python.org/dev/peps/pep-0484/#stub-files

的Python 2.7中使用存根文件类型提示

但是我不能让它适用于子类中的方法签名。

在存根文件中a.pyi:

class A(object):
    def foo(self, timestamp: float): ...

在Python 2.7文件b.py

class B(A):
    def foo(self, timestamp):
        print(timestamp)  # Inferred type of timestamp is not float!

PyCharm 2017.3.3不会将时间戳推断为浮点数。我没有检查mypy的行为。

有两种解决方法会导致代码冗余(不是首选)

解决方法1

在存根文件b.pyi

class B(A):
    def foo(self, timestamp: float): ...

解决方法2

在Python 2.7文件b.py

class B(A):
def foo(self, timestamp):  # type: (float) -> None
    print(timestamp)

1 个答案:

答案 0 :(得分:1)

如果您没有为函数添加类型注释,则表示您不希望PEP-484兼容类型检查器检查该功能。

这意味着您需要执行方法2:显式添加类型提示,以便Pycharm(和mypy)知道您希望对该函数进行类型检查。

请注意,您的解决方法1并不真正起作用:如果添加* .pyi文件,则告诉typechecker完全忽略相应的* .py文件。这可能不是你想要在这里发生的事情。

更广泛地说,Pycharm(或mypy)推断timestamp始终是float类型实际上是不正确的:实际加宽的子类型是合法的参数类型。例如,可能是B的时间戳方法接受浮点数或者strs:

class B(A):
    def timestamp(self, timestamp):
        # type: (Union[float, str]) -> None
        print(timestamp)

或者可以扩大接受任何类型:

class B(A):
    def timestamp(self, timestamp):
        # type: (object) -> None
        print(timestamp)

这两个定义都是A的有效子类型:它们都匹配A.timestamp的签名而不违反Liskov substitution principle

因此,由于我们无法轻易自动推断子类型的签名应该是什么,因此Pycharm(和mypy)不会尝试。