Как я могу отобразить вложенный именованный кортеж в класс с вложенными "полями данных"?
У меня есть класс 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