【问题标题】:Tell pycharm to infer types from superclass' methods?告诉 pycharm 从超类的方法中推断类型?
【发布时间】:2017-11-30 15:00:31
【问题描述】:

我正在编写一个库,其中有一个应该由用户子类化的类。我在该类中添加了类型提示,希望它们也会影响子类,这样用户就不必自己添加类型提示。

但是,它不起作用:

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


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

B.d 中变量d 的推断类型是Any,但我希望它是dict。有什么方法可以告诉 pycharm 它是 dict 而无需编写另一个类型提示?此类情况有什么通用做法吗?

【问题讨论】:

  • d 只是一个传入的 var,你用它做什么?您的第二个功能是覆盖已知的功能 a
  • 我用 d 做什么并不重要。现在我只关心类型推断。我希望 A.a 的类型提示适用于 B.a。有可能吗?
  • 简短版:它不是严格可推断的,但这是一个合理的假设;我不知道在 pycharm 中这样做的方法,但它值得一个功能请求,或者,因为它是社区支持的,甚至可能添加你自己。但实际上,您应该在任何地方都明确说明。

标签: python pycharm


【解决方案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 很难证明你确实是指同一件事,在实践中,大多数人都会使用它,所以这样做的选项会很有用。

最后一件事......今天,函数注释只是“仅供参考”,但有些项目正试图将它们实际用于事物......例如,装饰器将在调用函数之前检查参数类型。即使 PyCharm 可以推断注释,代码本身在运行时也不会,如果您希望它们用于任何功能,您可能必须继续明确地包含它们。

【讨论】:

    猜你喜欢
    • 2011-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多