签名不同于重写的 'save' 方法,pylint(signature-differs)

Signature differs from overidden 'save' method, pylint(signature-differs)

我能得到一些帮助来理解 pylint 消息 Signature 不同于覆盖的 'save' 方法,pylint(signature-differs) 指的是什么吗?:

def save(self, *args, **kwargs):
    """
    Override the original save method and update the number of
    seats available
    """
    reservations = (
        Booking.objects.aggregate(
            num_passengers=Count("passengers")
        )
        ["num_passengers"] or 0
    )
    self.seats_available = self.destination.max_passengers - reservations
    super().save(*args, **kwargs)

Django docs“如果你在你的方法定义中使用 *args,**kwargs,你保证你的代码将自动支持那些(更新的方法) 添加参数时。"

我不完全理解签名的工作原理,但我的理解是它与确保参数匹配有关。在这种情况下,我认为我没有更改默认保存方法的任何内容...那么是什么导致了这个问题?

我刚刚遇到这个问题,并且一直在尝试自己解决这个问题。我不明白确切的细节,但我相信我找到了一般推理。

基本上 def save(self, *args, **kwargs)save 限制更少 method in the Django Docs:

def save(self, force_insert=False, force_update=False, using=None,
          update_fields=None)

您会注意到,如果您从文档中复制并粘贴 save 方法的参数而不是 *args, **kwargs,错误就会消失。

那是因为理论上使用 *args, **kwargs 作为参数允许您将额外的参数传递给该方法,这违反了 LSP Principle (See conversation here 的一个明确示例)。替换中的参数必须等于或比父方法更严格。他们不应该允许你传递额外的参数。

然而,在实践中,Django 永远不会这样做,除非你自己编写代码来做到这一点,所以我认为在这种情况下作为警告相对不重要。我想 Django 开发人员推荐 shorthand *args, **kwargs 因为它更容易在许多方法中用作替代品,而不必记住每个单独的 class 或方法的具体参数。我想它属于 Python 风格指南建议之一 when it is better to be inconsistent with recommendations

希望有所帮助!