Python 3.6与3.7中tuple子类实例化的向后不兼容变更问询
tuple子类实例化行为的跨版本差异(Python 3.6 → 3.7)
版本间的具体行为变更
针对完全相同的tuple子类构造调用,两个版本的处理逻辑存在明确的不兼容区别:
- Python 3.6 对无自定义构造逻辑的tuple子类,只要传入任意关键字参数,就会直接触发入参校验错误,抛出
TypeError终止实例化流程 - Python 3.7 对同样的构造调用不会触发任何错误,传入的所有关键字参数会被静默忽略,最终返回一个空的tuple实例
对应实际运行效果的对比:
Python 3.6 运行表现
>>> class Tup(tuple): ... pass ... >>> Tup(x=123) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'x' is an invalid keyword argument for this function
Python 3.7 运行表现
>>> class Tup(tuple): ... pass ... >>> Tup(x=123) ()
行为差异的底层原因
这个差异本质是CPython核心针对内置类型构造逻辑做的一次兼容调整:
- 在Python 3.6及更早版本中,tuple原生的
__new__方法会执行严格的入参校验:只要收到不在定义参数列表内的关键字参数,就会立刻抛出参数不合法的TypeError,不会进入后续构造流程。 - 在Python 3.7及之后版本中,开发团队调整了内置容器类的默认
__new__校验规则:对于未重写__new__/__init__方法的tuple子类,原生构造逻辑会默认忽略所有未被显式识别的关键字参数,不再对这类入参做强制报错拦截。 - 这次调整的设计初衷是解决历史长期存在的兼容问题:此前大量业务代码会通过继承tuple的方式扩展自定义属性,在子类的
__init__方法中接收自定义关键字参数;但旧版严格的父类参数校验会在子类初始化逻辑执行前就抛出错误,直接阻断了这类完全合法的自定义扩展写法。
内容的提问来源于stack exchange,提问作者no step on snek
相关产品推荐
相关产品推荐

