2

I am trying to define a a class of namedtuples that contains an array, but with no success.

I have tried using np.zeros(shape=(16)) or np.empty(2, dtype = int8) but with no success.

from typing import NamedTuple
import numpy as np

class BasicDemodStatsMsg(NamedTuple):

    header: IcdHeader

    field1: np.uint32

    field2: np.uint32

    field3: np.uint16

    reserved: np.zeros(shape=(16))

    checksum: np.uint16

At the end I would like to have a class that has a fixed size of bytes in the memory and can be packed and unpacked to and from byte arrays.

mkrieger1
  • 19,194
  • 5
  • 54
  • 65

1 Answers1

3

Your issue is related to the data type; np.zeros() is a method which returns np.ndarray, the actual data type. This is fine:

>>> class BasicDemodStatsMsg(typing.NamedTuple):
...     field1: np.uint32
...     field2: np.uint32
...     field3: np.uint16
...     checksum: np.uint16
...     reserved: np.ndarray = np.zeros(shape=16)
...
>>>

You should be extremely wary about how reserved is used, as it's a mutable default argument. It may be more appropriate to use a dataclass and a therefore allow yourself to use the default factory to create it.

from dataclasses import dataclass, field
from typing import NamedTuple

@dataclass
class BasicDemodStatsMsg(NamedTuple):
    field1: np.uint32
    field2: np.uint32
    field3: np.uint16
    checksum: np.uint16
    reserved: np.ndarray = field(default_factory=lambda: np.zeros(shape=16, dtype=np.uint8))

Note that the default attribute is the last one declared; this is because non-default fields can't follow defaults in named tuples.

Ben
  • 51,770
  • 36
  • 127
  • 149
  • i need to specify the type of the array, for example uint8, which does not happen in your solution. – Yarom Swissa Aug 29 '19 at 10:39
  • You can just specify the type normally @Yarom: `reserved: np.ndarray = field(default_factory=lambda: np.zeros(shape=16, dtype=np.uint8))` I've also updated the answer to demonstrate this. – Ben Aug 29 '19 at 12:27