重写方法时,陈述(无关)参数的首选方式是什么



假设以下代码:

class A:
def foo(self, bar, baz=None, *args, **kwargs):
... # Do some stuff with using bar, baz, args and kwargs
return result

class B(A):
def foo(self, *args, **kwargs):
... # Not using bar or baz
return super().foo(*args, **kwargs)

class C(A):
def foo(self, bar, baz=None, *args, **kwargs):
... # Not using bar or baz
return super().foo(bar, baz, *args, **kwargs)

正如您所看到的,有两种方法可以覆盖foo。类C显式地声明参数,而类B只是在*args*kwargs中抛出它们。两者都很好。我想,如果我使用bazbar,我会明确说明它们可以提高可读性,并为我节省字典/列表调用。但如果我不使用它们,我认为将它们包装成*args**kwargs应该没问题。有什么更可取的方法和理由吗?

你明白了。如果你不使用bar/baz,不要接受它们,只需将它们作为args/kwargs的一部分传递,而不用自己处理它们。

一个半官方的建议(参见实用建议部分(,尤其是在更复杂的继承场景中,是根本不接受*args(除非你真的需要接受可变位置的参数,而不是懒惰地不陈述父母要求的已知、固定数量的参数(,并且每层都只接受:

  1. 他们使用的参数,以及
  2. 任意关键字参数(**kwargs(

原因是:

  1. 位置参数可能会随着层次结构的修改而更改位置
  2. 当涉及多重继承(或者更糟的是,菱形继承(时,弄清楚位置参数的最终顺序会变得非常难看

要求所有参数通过关键字传递稍微慢一点,但通过super()调度进行许多调用的开销很小,而且传递和不传递哪些参数非常清楚。所以对于你的代码,你只需要做:

class A:
def foo(self, bar, baz=None, **kwargs):
... # Do some stuff with using bar, baz, and kwargs
return result
class B(A):
def foo(self, **kwargs):
... # Not using bar or baz
return super().foo(**kwargs)
class C(A):
# ... same as B aside from omitted code

来电者呼叫:

instance.foo(bar=1)
instance.foo(bar=2, baz=3)

或类似物。

最新更新