【问题标题】:Is there a proper way to implement a subclass with a different method signature than its super class in Python?是否有一种正确的方法来实现具有与 Python 中的超类不同的方法签名的子类?
【发布时间】:2020-02-07 04:48:31
【问题描述】:

我已将超类定义为其他开发人员将编写子类来实现的正式接口,但是方法的参数会因实现而异:

class FormalInterface:
  """ Subclasses will have varying arguments for formal_method """
  def formal_method(*args, required_arg=0):
    raise NotImplemented('Implement me')

  def get_arguments():
    """ Tells the user what arguments need to be passed """
    raise NotImplemented('Implement me')


class MyImplementationOf(FormalInterface):
  def formal_method(concrete_arg1, conrete_arg2, required_arg=0)
    # impelementation...

  def get_arguments():
    return 'concrete_arg1', 'concrete_arg2', 'required_arg'

这是合法的 Python 代码,但是关于重新定义函数签名的警告比比皆是。

在这种情况下我是否可以忽略警告?还是我应该考虑一种更 Pythonic 的方法?

【问题讨论】:

  • 您看到了什么警告?上面的运行对我没有任何警告。
  • 警告来自 PyCharm 和 PyLint 等代码检查工具,当我覆盖这些警告时,我想确保我可以证明覆盖是合理的,但我不确定在这种情况下我能做到。

标签: python interface signature super subclassing


【解决方案1】:

super-considered-super blog post 中有关于如何处理这种情况的建议。

一种方法是仅使用关键字参数,剥离您需要的参数并使用**kwargs 将剩余参数委托给其他方法:

class A:
    def m(self, *, x, y):
        print(f'{type(self)=}   {x=}   {y=}')

class B(A):
    def m(self, *, z, **kwargs):
        super().m(**kwargs)
        print(f'{type(self)=}   {z=}')

这样调用方法:

>>> A().m(x=10, y=20)
type(self)=<class '__main__.A'>   x=10   y=20
>>> B().m(x=10, y=20, z=30)
type(self)=<class '__main__.B'>   x=10   y=20
type(self)=<class '__main__.B'>   z=30

【讨论】:

    猜你喜欢
    • 2021-11-10
    • 2019-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-29
    • 1970-01-01
    • 2016-04-05
    相关资源
    最近更新 更多