【发布时间】:2020-05-16 22:21:31
【问题描述】:
我正在构建一个可以接受不同初始化方式的 typing.NamedTuple 类(see typing.NamedTuple docs here,或者它继承自旧的 collections.namedtuples docs)。
为什么在这种情况下使用 NamedTuple?我希望它是不可变的和自动哈希的,所以它可以是一个字典键,我不必编写哈希函数。
我知道我需要使用 __new__ 而不是 __init__,因为 NamedTuples 是不可变的(例如,see this Q&A。我已经搜索过并且有一些花絮(例如answers to this question on setting up a custom hash for a namedtuple),但是我无法让一切正常工作,我收到一个关于无法覆盖 __new__ 的错误。
这是我当前的代码:
from typing import NamedTuple
class TicTacToe(NamedTuple):
"""A tic-tac-toe board, each character is ' ', 'x', 'o'"""
row1: str = ' '
row2: str = ' '
row3: str = ' '
def __new__(cls, *args, **kwargs):
print(f'Enter __new__ with {cls}, {args}, {kwargs}')
if len(args) == 1 and args[0] == 0:
new_args = (' ', ' ', ' ')
else:
new_args = args
self = super().__new__(cls, *new_args, *kwargs)
return self
if __name__ == '__main__':
a = TicTacToe(('xo ', 'x x', 'o o'))
print(a)
b = TicTacToe(0)
print(b)
但我收到以下错误:
Traceback (most recent call last):
File "c:/Code/lightcc/OpenPegs/test_namedtuple.py", line 4, in <module>
class TicTacToe(NamedTuple):
File "C:\Dev\Python37\lib\typing.py", line 1384,
in __new__
raise AttributeError("Cannot overwrite NamedTuple attribute " + key)
AttributeError: Cannot overwrite NamedTuple attribute __new__
我不能为继承自 NamedTuple 的子类创建单独的 __new__ 函数吗?从消息中可以看出,它正在尝试直接覆盖 NamedTuple 的 __new__,而不是 TicTacToe 类。
这是怎么回事?
【问题讨论】:
标签: python inheritance constructor immutability namedtuple