当前位置: 首页 > 知识库问答 >
问题:

继承了带有工厂的NamedTuple类

苏嘉歆
2023-03-14

我有一个类,用于使用struct解码二进制数据并存储在NamedTuple中,如下所示:

class HEADER1(NamedTuple):
    name: str
    u2: int
    tracetime: int
    u4: int
    u5: int
    u6: int
    u7: int
    struct = Struct('<8s6L')

    @classmethod
    def unpack(cls, data):
        return cls(*cls.struct.unpack(data))

这是没有问题的,我可以如下使用:

h = HEADER1.unpack(b'svpt_str\x03\x01\x00\x00\xae\xa6i_\xd0\x03\xfe3\x00\x00\x00\x00P\xa0\xdc3\x00\x00\x00\x00')

但是,如果我尝试将其更改为继承类方法,如下所示,它会失败:

class NamedTupleUnpack(NamedTuple):
    struct = Struct('x')
    @classmethod
    def unpack(cls, data):
        return cls(*cls.struct.unpack(data))

class HEADER1(NamedTupleUnpack):
    name: str
    u2: int
    tracetime: int
    u4: int
    u5: int
    u6: int
    u7: int
    struct = Struct('<8s6L')

然后它错误与TypeError:__new__()接受1个位置参数,但给出了8个

我知道从NamedTuple继承有些问题,但我想知道是否有解决办法?

编辑:正如下面的其他人所暗示的那样,看起来数据类是要走的路:一种用于类型检查目的的子类命名Tuple的方法

共有2个答案

微生旻
2023-03-14

我尝试使用mixin,例如:

class HEADER1(Unpack, NamedTuple): 
    # Mixins evaluate right to left so NamedTuple is the base
    ...

但是,NameTuple也不能与mixins一起使用,而且unpack方法在派生的Tuple中不可用。

所以我使用了dataclass,它确实有效(并添加了更多功能):

from typing import NamedTuple
from struct import Struct
from dataclasses import dataclass, fields
from abc import ABCMeta, abstractproperty
from collections.abc import Sequence

class Unpack(Sequence, metaclass=ABCMeta):
    @abstractproperty
    def struct(self):
        pass
    @classmethod
    def unpack(cls, data):
        return cls(*cls.struct.unpack(data))
    def __getitem__(self, i):
        return getattr(self, fields(self)[i].name)
    def __len__(self):
        return len(fields(self))

@dataclass(order=True)
class HEADER1(Unpack):
    # Note Mixin's evalute right to left so NamedTuple is the base
    name: str
    u2: int
    tracetime: int
    u4: int
    u5: int
    u6: int
    u7: int
    struct = Struct('<8s6L')

h = HEADER1.unpack(b'svpt_str\x03\x01\x00\x00\xae\xa6i_\xd0\x03\xfe3\x00\x00\x00\x00P\xa0\xdc3\x00\x00\x00\x00')
h
HEADER1(name=b'svpt_str', u2=259, tracetime=1600759470, u4=872285136, u5=0, u6=870096976, u7=0)
韦飞尘
2023-03-14

键入。NamedTuple没有提供您想要的功能,因为向NamedTuple类的子类添加字段与namedtuples的设计意图冲突。

设计意图是,如果Foo是一个带有n字段的名称元组类,则Foo的实例应该和n-元素元组一样。例如,如果n==3,那么您应该能够获取Foo的任意实例并执行

a, b, c = foo

添加字段打破了这一点。如果您可以创建一个带有第四个字段的子类< code>class Bar(Foo),那么< code>Bar的实例就是< code>Foo的实例,而您不能这样做

a, b, c = bar

您的NamedTupleUnpack是一个有0个字段的namedtuple类。不能在HEADER1子类中添加字段。

您可能应该使用常规类,或者dataclasses,或者将解包放入mixin。

 类似资料:
  • 问题内容: 我正在开发一个使用angular作为客户端框架的应用程序,目前使用angular作为岩石,我真的很高兴,尽管现在我发现我经常复制和粘贴要组织成类层次结构的代码。例如,对话框共享一组通用的功能,需要打开,关闭它们,提供功能的代码也是从某些父BaseTypeaheadClass继承的首选对象,尽管我在angular中没有发现的一件事是组织这些层次结构。控制器,服务和提供者都在下面使用普通的

  • 我读到,在基于XML的Spring配置中bean可以继承工厂方法。 我尝试实现了它: 控制器接口: ControllerFactory类: SampleController实现: 如何更改它以使工厂方法bean继承正确实现? 将工厂方法配置复制到子bean可以正常工作:

  • 问题内容: 使用基于注释的配置(等)是否可以实现相同的bean继承? http://docs.spring.io/spring/docs/4.1.0.BUILD-SNAPSHOT/spring-framework- reference/htmlsingle/#beans-child-bean- definitions 问题答案: java config中没有抽象bean的概念,因为Java语言已经

  • 我有一个DAO接口,其中有多个实现,我希望其中一个是Room实现(Kotlin):

  • 使用基于注释的配置(等)是否可以实现相同的bean继承? http://docs.spring.io/spring/docs/4.1.0.BUILD-SNAPSHOT/spring-framework-reference/htmlsingle/#beans-child-bean-definitions

  • FAQs in section [24]: [24.1] 如何表示“私有继承”? [24.2] 私有继承和组合(composition)有什么类似? [24.3] 我应该选谁:组合还是私有继承? [24.4] 从私有继承类到父类需要指针类型转换吗? [24.5] 保护继承和私有继承的关系是什么? [24.6] 私有继承和保护继承的访问规则是什么? 24.1 如何表示“私有继承”? 用 : priv