Как я могу отобразить вложенный именованный кортеж в класс с вложенными "полями данных"?

У меня есть класс Python class PointStamped который позволяет определять вложенные "поля данных" (например, p.header.frame_id="test", увидеть ниже). Я хотел бы отобразить поля соответствующего именованного кортежа PointStampedNamedtuple = namedtuple('PointStamped', 'Header Point') к этому к этому классу. Это можно сделать явно (как в примере в конце этого вопроса). Однако я бы предпочел реализовать отображение без необходимости явного присваивания значений полей namedtuples классу "поля данных". Я думал о чем-то вроде псевдокода ниже:

# PSEUDO CODE
def map(namedtuple):
    """
    Maps the namedtuple keys and values to corresponding class "data fields".
    Takes namedtuple as argument, returns instance with accordingly initialized "data field" values.
    """
    for every key in namedtuple:
        get key value
        assign key value to corresponding class "data field"

# which could be used somehow like...
p = convert(PointStampedNamedtuple(header=(seq=0, stamp=(0, 0), frame_id="test"),
                                   point=(x=2.0, y=0.0, z=0.0))

# with "data field" values of `p` assigned as follows

print(p)
# header: 
#   seq: 0
#   stamp: 
#     secs: 0
#     nsecs:         0
#   frame_id: test
# point: 
#   x: 2.0
#   y: 0.0
#   z: 0.0

Как это можно сделать проще всего?


Класс позволяет определять данные, например, следующим образом:

>>> from geometry_msgs.msg import PointStamped
>>> p = PointStamped()
>>> p.header.frame_id = "test"
>>> p.point.x = 2.0

Соответствующий класс приводит к:

>>> print(p)
header: 
  seq: 0
  stamp: 
    secs: 0
    nsecs:         0
  frame_id: test
point: 
  x: 2.0
  y: 0.0
  z: 0.0

Конструктор класса выглядит следующим образом:

class PointStamped(genpy.Message):
  ...

  def __init__(self, *args, **kwds):
    """
    ...

    :param args: complete set of field values, in .msg order
    :param kwds: use keyword arguments corresponding to message field names
    to set specific fields.
    """
    if args or kwds:
      super(PointStamped, self).__init__(*args, **kwds)
      #message fields cannot be None, assign default values for those that are
      if self.header is None:
        self.header = std_msgs.msg.Header()
      if self.point is None:
        self.point = geometry_msgs.msg.Point()
    else:
      self.header = std_msgs.msg.Header()
      self.point = geometry_msgs.msg.Point()

Именованные кортежи PointStampedNamedtuple = namedtuple('point_stamped', 'header point') имена полей header а также point имеют тип namedtuple header = namedtuple('header', 'seq stamp frame_id') (stamp сопоставляется с именами полей secs а также nsecs) а также Point = namedtuple('point', 'x y z') сам.

Явное отображение именованного кортежа в класс возможно следующим образом (но я ищу более простую, "неявную" реализацию отображения):

>>> p = PointStamped()
>>> namedtuple = PointStampedNamedtuple()
>>> namedtuple.header.seq = 0
>>> namedtuple.header.stamp.secs = 0
>>> namedtuple.header.stamp.nsecs = 0
>>> namedtuple.header.frame_id = "test"
>>> namedtuple.point.x = 2.0
>>> namedtuple.point.y = 0.0
>>> namedtuple.point.z = 0.0
>>> p.header.seq = namedtuple.header.seq
>>> p.header.stamp.secs = namedtuple.header.stamp.secs
>>> p.header.stamp.nsecs = namedtuple.header.stamp.nsecs
>>> p.header.frame_id = namedtuple.header.frame_id
>>> p.point.x = namedtuple.point.x
>>> p.point.y = namedtuple.point.y
>>> p.point.z = namedtuple.point.z

0 ответов

Другие вопросы по тегам