如何将递归 `.json()` 方法添加到 **NamedTuple** 的子类
How to add recursive `.json()` method to subclass of **NamedTuple**
我目前有几个 classes 遵循下面代码中描述的模式:
from typing import NamedTuple
class Data(NamedTuple):
name: str,
value: float
def json(self):
return {'name': self.name, 'value': self.value}
我不想在我创建的每个新 class 中定义一个 json
方法,我想扩展 typing.NamedTuple
,这样我就可以从我的新 class 扩展] 而不必在 subclasses 中定义 json 方法。 typing.NamedTuple
已经提供了 _asdict
方法,但是这个方法是不够的,因为它不是递归的(Nested namedtuples 不会被转换为 dict 对象)。
我已经尝试在下面的代码中尝试这样做:
class JsonNamedTuple(NamedTuple):
def json(self):
# some slightly complex recursive code here
class Data(JsonNamedTuple):
name: str,
value: float
a = Data('asdf', 0.5)
我收到这个错误:
TypeError: <lambda>() takes 1 positional argument but 3 were given
有没有办法扩展 typing.NamedTuple
而不会出现此错误?
遗憾的是,您实际上无法扩展 typing.NamedTuple
。
但是您可以像这样创建一个 class 装饰器:
import typing
class _JsonMixin:
def json(self):
# some slightly complex recursive code here
return {'name': self.name, 'value': self.value}
def jsonable(cls):
cls.__bases__ = (_JsonMixin,) + cls.__bases__
return cls
@jsonable
class Data(typing.NamedTuple):
name: str
value: float
思维类型检查员不会理解 .json()
从何而来。
修改 __bases__
优于创建新的 class 并继承 cls
,并且与注入 .json()
.
不同,可以轻松支持更多方法
如果您不想使用 class 装饰器,您可以创建一个元 class,但这有点复杂。 metaclass 也不适用于类型检查器。
我目前有几个 classes 遵循下面代码中描述的模式:
from typing import NamedTuple
class Data(NamedTuple):
name: str,
value: float
def json(self):
return {'name': self.name, 'value': self.value}
我不想在我创建的每个新 class 中定义一个 json
方法,我想扩展 typing.NamedTuple
,这样我就可以从我的新 class 扩展] 而不必在 subclasses 中定义 json 方法。 typing.NamedTuple
已经提供了 _asdict
方法,但是这个方法是不够的,因为它不是递归的(Nested namedtuples 不会被转换为 dict 对象)。
我已经尝试在下面的代码中尝试这样做:
class JsonNamedTuple(NamedTuple):
def json(self):
# some slightly complex recursive code here
class Data(JsonNamedTuple):
name: str,
value: float
a = Data('asdf', 0.5)
我收到这个错误:
TypeError: <lambda>() takes 1 positional argument but 3 were given
有没有办法扩展 typing.NamedTuple
而不会出现此错误?
遗憾的是,您实际上无法扩展 typing.NamedTuple
。
但是您可以像这样创建一个 class 装饰器:
import typing
class _JsonMixin:
def json(self):
# some slightly complex recursive code here
return {'name': self.name, 'value': self.value}
def jsonable(cls):
cls.__bases__ = (_JsonMixin,) + cls.__bases__
return cls
@jsonable
class Data(typing.NamedTuple):
name: str
value: float
思维类型检查员不会理解 .json()
从何而来。
修改 __bases__
优于创建新的 class 并继承 cls
,并且与注入 .json()
.
如果您不想使用 class 装饰器,您可以创建一个元 class,但这有点复杂。 metaclass 也不适用于类型检查器。