告诉pycharm推断超类中的类型'方法?

时间:2017-06-27 13:59:50

标签: python pycharm

我正在编写一个库,其中我有一个应该被用户子类化的类。我已经为该类添加了类型提示,希望它们也会影响子类,以便用户不必自己添加类型提示。

但是,它不起作用:

# Class from the library
class A:
    def a(self, d: dict):
        raise NotImplementedError()


# User-defined subclass
class B(A):
    def a(self, d):
        ...

d中的变量B.d的推断类型为Any,但我希望它为dict。有没有办法告诉pycharm它没有写另一个类型提示dict?这种情况有没有常见做法?

1 个答案:

答案 0 :(得分:1)

这不是C ++,其中超类定义了签名,子类实现了它。在python中,一切都是明确的...... A.aB.a具有不同的签名并且具有完全不同的参数列表是不好的形式,但实际上并不允许它:

In [7]: class A(object):
   ...:     def a(self, x, y, z):
   ...:         print (x, y, z)
   ...:         

In [8]: class B(A):
   ...:     def a(self, m, n, o):
   ...:         print (m + n + o)
   ...:         

In [9]: b = B()
In [10]: b.a(1,2,3)
6
In [11]: a = A()
In [12]: a.a(1,2,3)
1 2 3

现在,在现实世界中,如果你真的用你期望人们使用的类来做这样的事情,那么他们会正确地尖叫并将你踢出项目...可预测的API是继承的核心部分。

这是可能的,因为与C ++不同,函数查找是通过多态的签名完成的(例如,您可以编写int f(int a);int f(float f);,它们是两个具有相同名称的独立函数,编译器知道哪一个调用调用者使用的参数类型,Python函数查找仅在名称上。

但即使假设签名与超类相同,技术上错误,因为PyCharm将很难证明你确实意味着同样的事情,在实践中,大多数人都会使用它,所以选择这样做会很有用。

最后一件事......今天,函数注释只是' fyi',但是有些项目试图将它们用于实际的东西......装饰者会在调用之前检查参数类型例如,功能。即使PyCharm可以推断注释,代码本身在运行时也不会胜任,如果你想要它们用于任何功能,你可能必须继续明确地包含它们。