【问题标题】:python typing abstractmethod with default argumentspython用默认参数输入abstractmethod
【发布时间】:2021-11-15 22:50:57
【问题描述】:

我有点困惑我应该如何键入基类抽象方法?

在这种情况下,我的基类只要求继承类实现一个名为“learn”的方法,该方法返回 None 而无需任何参数。

class MyBaseClass(ABC):
    @abstractmethod
    def learn(self, *args, **kwargs) -> None:
       raise NotImplementedError()

但如果我实现它 mypy 引发错误“学习”的签名与超类型“MyBaseClass”不兼容'

class MyOtherClass(MyBaseClass):
    def learn(self, alpha=0.0, beta=1) -> None:
       # do something
       return None

那么我应该如何在基类中声明learn方法呢?

【问题讨论】:

标签: python python-3.x mypy


【解决方案1】:

首先,我会问你为什么想要一个没有已知参数的方法。这听起来像是一个设计问题。

一个解决方案

如果这些参数具有默认值(并且基类不使用**kwargs),则可以向子类添加新参数,例如

class MyBaseClass:
    @abstractmethod
    def learn(self) -> None:
       raise NotImplementedError()

class MyOtherClass(MyBaseClass):
    def learn(self, alpha=0.0, beta=1) -> None:
       ...

虽然你不能指定alphabeta,如果你只知道它是MyBaseClass

def foo(x: MyOtherClass) -> None:
    x.learn(alpha=3)  # ok

def foo(x: MyBaseClass) -> None:
    x.learn(alpha=3)  # not ok

为什么*args, **kwargs 不起作用?

如果你有

class MyBaseClass(ABC):
    @abstractmethod
    def learn(self, *args, **kwargs) -> None:
       raise NotImplementedError()

然后考虑函数

def foo(x: MyBaseClass) -> None:
    ...

在该函数中,您可以将任何内容传递给x.learn,例如x.learn(1, fish='three')。任何x 都必须如此。由于x 可以是MyBaseClass 子类的实例(例如MyOtherClass),因此该子类也必须能够接受这些参数。

【讨论】:

  • 我认为 *args, **kwargs 会起作用,但 mypy 会抱怨
  • @Gavello works fine for me。我相信 *args, **kwargs 不会因为我上面所说的原因而工作
猜你喜欢
  • 2018-10-07
  • 2017-08-04
  • 1970-01-01
  • 2017-01-07
  • 2021-10-14
  • 1970-01-01
  • 2012-08-01
  • 2018-11-16
  • 2020-09-04
相关资源
最近更新 更多