You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中默认定义*args和**kwargs用于未来继承是否为不良实践?

为什么不建议在基类和子类方法中滥用*args和**kwargs?

你的思路本质是想通过模糊参数签名来实现“兼容未来变化”,但这种做法会带来一堆实际工程上的问题,这也是它不被广泛采用的原因:

1. 可读性与维护性暴跌

方法签名是代码的“说明书”,如果所有方法都用*args和**kwargs,其他开发者(包括未来的你)完全不知道这个方法到底需要什么参数、哪些参数是必填的。比如:

class Subscriber:
    def send_notification(self, *args, **kwargs):
        pass

class GoldSubscriber(Subscriber):
    def send_notification(self, *args, **kwargs):
        title = args[0]
        content = args[1]
        priority = kwargs.get('priority', 'normal')
        # 逻辑处理

别人调用send_notification时,根本不知道要传标题、内容,也不知道有priority这个可选参数,必须去翻方法内部实现,维护成本直接拉满。

2. 隐藏低级错误

如果调用时传错了参数名(比如把priority写成prioritiy),或者传了多余的参数,因为**kwargs会默默忽略未使用的键,程序不会报错,但逻辑会不符合预期。这种错误排查起来极其麻烦——你很难想到是参数拼写错了,因为代码没有任何报错提示。

3. 违反里氏替换原则(LSP)

多态的核心是子类可以无缝替换基类,但如果子类的方法依赖*args/**kwargs里的额外参数,而基类不需要,就会出现问题:

# 基类调用没问题
sub = Subscriber()
sub.send_notification("标题", "内容")

# 子类替换后,因为需要priority参数,直接报错
sub = GoldSubscriber()
sub.send_notification("标题", "内容")  # 内部取kwargs['priority']会KeyError

这反而破坏了你想要的“无需区分基类子类”的目标,调用方还是得判断类型,才能正确传参。

4. IDE工具支持完全失效

现代IDE的核心优势之一是根据方法签名提供参数提示、自动补全和类型检查。一旦用了*args/**kwargs,IDE完全不知道该提示什么,开发者只能靠记忆或者翻文档,不仅效率低,还容易出错。

5. 调试难度剧增

调试时,你无法直接从方法调用处看到传递的参数细节,必须在方法内部手动展开args和kwargs才能查看。比如想确认priority有没有传对,得写print(kwargs.get('priority')),而不是直接在调用处看参数。


更好的替代方案

其实有更优雅的方式实现你的需求:

  • 使用默认参数:子类扩展方法时,新增的参数设默认值,这样调用方无需修改代码:
    class Subscriber:
        def send_notification(self, title, content):
            pass
    
    class GoldSubscriber(Subscriber):
        def send_notification(self, title, content, priority="normal"):
            # 子类逻辑
            super().send_notification(title, content)
    
  • 封装参数对象:把相关参数打包成一个类,比如NotificationConfig,以后新增参数只需要修改这个类,方法签名保持不变:
    class NotificationConfig:
        def __init__(self, title, content, priority="normal"):
            self.title = title
            self.content = content
            self.priority = priority
    
    class Subscriber:
        def send_notification(self, config):
            pass
    
    class GoldSubscriber(Subscriber):
        def send_notification(self, config):
            # 利用config.priority做逻辑
            super().send_notification(config)
    
  • 依赖注入:如果子类需要的额外参数是服务或配置,通过构造函数注入,而不是在方法参数里传递:
    class GoldSubscriber(Subscriber):
        def __init__(self, notification_service, priority_level="high"):
            super().__init__(notification_service)
            self.priority_level = priority_level
    
        def send_notification(self, title, content):
            # 使用self.priority_level
            pass
    

内容的提问来源于stack exchange,提问作者Luihis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 08:35:18