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

Python是否存在SOLID范式违反?以FractionTuple子类化tuple为例

Python中继承内置类型违反LSP的常见性分析

你提到的FractionTuple继承tuple并强化__new__方法前置条件的写法,确实违反了里氏替换原则(LSP):基类tuple允许传入任意可迭代对象创建实例,而FractionTuple仅接受两个整数参数,导致原本使用tuple的代码替换成FractionTuple后会直接报错。

针对你的问题,具体分析如下:

这种违反LSP的写法是否常见?

  • 不算主流实践,但并非罕见,尤其在处理Python内置不可变类型时更为普遍。
  • 核心原因是Python的内置不可变类型(如tuple、str、frozenset)依赖__new__方法创建实例,而非普通的__init__。如果要对实例的创建规则做约束,几乎必然要强化__new__的前置条件,这就会直接违反LSP。
  • 很多开发者会在「需要复用内置类型的全部/大部分行为,但又要添加特定约束」的场景下采用这种写法,比如自定义的受限容器、特定格式的字符串类等。

是优先代码复用还是例外情况?

  • 这属于场景化的权衡选择,而非普遍优先代码复用而放弃LSP。
  • 当开发者明确FractionTuple的定位是「专门的分数表示工具」,而非「通用tuple的替代品」时,LSP的约束就不再是核心要求——用户从一开始就不会把它当成普通tuple来使用,自然不会触发替换后的兼容性问题。
  • 如果是需要严格遵循OO原则的场景,开发者通常会选择组合而非继承:内部维护一个tuple实例,对外按需暴露方法,既复用了功能,又不违反LSP。示例代码如下:
    class FractionTuple:
        def __init__(self, p, q):
            if not isinstance(p, int) or not isinstance(q, int):
                raise TypeError("Both elements must be integers")
            self._inner_tuple = (p, q)
        
        def __getitem__(self, index):
            return self._inner_tuple[index]
        
        def __len__(self):
            return len(self._inner_tuple)
        
        # 按需实现其他需要的tuple方法,比如__iter__、__repr__等
    

总结

FractionTuple不是个例,但也不是Python社区的默认选择。开发者在OO设计上会同时考虑SOLID原则和实际需求:当复用内置类型的收益显著,且能明确派生类的使用边界时,这种违反LSP的写法会被接受;反之,组合模式是更安全的选择。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 05:03:20