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.

10
  • 1
    Have you successfully defined such a class that does not contain an array? Commented Aug 29, 2019 at 8:31
  • yes, without the array it works perfectly Commented Aug 29, 2019 at 8:32
  • 1
    And what is NamedTuple? Where does it come from? Commented Aug 29, 2019 at 8:35
  • 1
    It's collections.namedtuple not collections.NamedTuple @Yarom. Commented Aug 29, 2019 at 8:40
  • 1
    As @Ben said collections.namedtuple is a thing. The only NamedTuple I can think of right now is typing.NamedTuple and that is only for typing purpose. Commented Aug 29, 2019 at 8:42

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

2 Comments

i need to specify the type of the array, for example uint8, which does not happen in your solution.
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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.