python - 3.6 和 3.7 之间子类化的向后不兼容更改

标签 python tuples subclass

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)
()

3.6 和 3.7 之间发生了什么变化?为什么?

最佳答案

较新版本的 Python 中的行为是一个错误。

版本 3.6 和 3.7 之间的变化来自于 tuple 处理其参数的方式。在 3.6 及更早版本中,tuple 的单个可选参数可以按位置传递(正常的、有记录的方式),也可以使用未记录的名称 sequence 作为关键字参数传递。论证。

>>> tuple(sequence="ab") # this only works on Python versions prior to 3.7
('a', 'b')

Python 3.7 删除了将参数作为关键字传递的功能。相反,它变成了仅限位置的论证。当时,只有内置函数可以有这种参数,尽管它们的语法记录在 PEP 457 中。 (并且它们可用于实现 PEP 570 的 Python 3.8 中的普通 Python 代码)。您可以在较新版本的 Python 中的 tuple 文档中看到仅位置参数语法,其中参数的性质通过在构造函数签名中添加斜杠(在单个仅位置参数):

>>> help(tuple) # in more recent versions of Python
Help on class tuple in module builtins:

class tuple(object)
 |  tuple(iterable=(), /)
[...]

不幸的是,更改的实现似乎对 tuple 子类中关键字参数的处理产生了一些意想不到的后果,因为继承的构造函数方法会默默地忽略它传递的所有关键字参数,而不是引发一个适当的异常(exception)(正如 3.6 及之前版本中针对 sequence 之外的任何关键字名称所做的那样)。

此问题已报告给 Python 开发人员,地址为 bug tracking system (也许是你做的?)。一旦确定了纠正该问题的最佳方法,我预计该问题将针对仍在接受错误修复的 Python 版本进行修复(当前为 3.8 和 3.9,但不包括仅获得安全修复的 3.7)。可能需要几个月的时间才能发布。

关于python - 3.6 和 3.7 之间子类化的向后不兼容更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66555290/

相关文章:

haskell - 如何在 Haskell 中将列表一分为二?

python - 使用 __dict__ 列出实例属性

python - Pytest 日志记录忽略 pytest.ini 中的选项

python - 在 csv 文件的特定列中插入数据

python - 如果第二个 df 之间存在匹配,如何从它们获取项目

python - .get 元组与字典

Python 类 __div__ 问题

python - 将嵌套元组转换为嵌套列表

dart - 在 Dart 中,如何从另一个文件中的子类访问父私有(private) var?

Python 子类化 - 如何更新另一个类属性使用的类属性