2015-01-17 4 views
0

Я хочу создать переменную, которая хранит некоторые точки за один ROI. Пусть говорят, что это что-то вроде:Namedtuple, который хранит точку

ROI.Point1.x 
ROI.Point1.y 
ROI.Point2.x 
ROI.Point2.y 
... 
ROI.PointN.x 
ROI.PointN.y 

Я пытался сделать это с namedtuple, например, так:

Point = namedtuple("Point", "x y") 
ROI = namedtuple("ROI", "Point1 Point2 Point3 ... PointN") 
ROI.Point1 = Point 
ROI.Point2 = Point 
... 
ROI.PointN = Point 

Я думаю, что это глупая идея. Потому что я должен определить всю точку с помощью «ROI ... = Point».

Если у меня только 1 ROI и какой-то момент, я думаю, что он работает нормально. Но как насчет того, чтобы много ROI со многими очками в них? Это кажется глупой идеей, но пока это работает.

Я также пытался использовать ROI.Point1, ROI.Point2, ..., ROI.PointN = Point, но у меня есть ошибка, которая говорит 'type' object is not iterable.

Не мог бы кто-нибудь помочь мне сделать его более простым способом, пожалуйста? Я не хотел делать другой класс, как другие люди.

+2

Почему вы не используете кортеж или список для хранения нескольких точек? – falsetru

+3

Вы не выполняете 'ROI.Point1 = Point'. Вы бы сделали ROI (Point (x1, y1), Point (..), ..) '. 'ROI' и' Point' являются * классами *. –

+0

Yups, идея хранения нескольких точек в кортеже. Насколько я знаю, namedtuple совпадает с кортежем, но он используется как индекс, а кортеж использует численный индекс. (CMIIW) @falsetru –

ответ

0

Похоже, вы должны использовать NamedTuple для Point, но обычный tuple для ROI.

roi3 = (Point(x1, y1), Point(x2, y2), Point(x3, y3)) 

единственная «хитрая» часть является то, что если у вас есть только одна точки синтаксис

roi1 = (Point(x1, y1),) # comma is needed to make a 1-tuple 

И, конечно, вы получите доступ точки с

roi[0], roi[1], ... roi[n-1] 

, а не по имя

+0

Почему вы можете использовать именованный кортеж для ROI просто отлично. –

+0

@MartijnPieters: Я бы сказал, что именованный кортеж, где имена «point1», «point2», ... не имеет большого смысла Разумеется, только мой взгляд. – 6502

+0

Да, последовательные имена, в которых нормальный кортеж будет делать, действительно бессмысленны, но основная путаница - от класса к экземпляру здесь. –

0

Я думаю, что лучше использовать словарь с точками. Вот идея:

from collections import namedtuple, defaultdict 
Point = namedtuple('Point', ['x', 'y']) 
ROI = defaultdict(Point) 
ROI['Point1'] = Point(1, 1) 
ROI['Point2'] = Point(5, 2) 
print(ROI['Point1'].x, ROI['Point1'].y) 
+0

Вы не получаете никакой пользы от использования 'defaultdict' здесь, поскольку это произойдет, если вы не сделаете это, например: «ROI = defaultdict (lambda: Point (0, 0))' – jonrsharpe

+0

Хм .. если я вижу вашу идею, это что-то вроде «ROI ... = Point» для каждого Если я не ошибаюсь, @Aris F. –

0

Вы пропустили что-то здесь: namedtuple()производит новый класс. Из documentation:

Возвращает новый кортеж подкласс имени имяТипа. Новый подкласс используется для создания объектов типа tuple, которые имеют поля, доступные для поиска атрибутов, а также индексируемые и повторяемые.

(Bold emphasis mine).

Используйте эти подклассы для создания новых экземпляров:

Point = namedtuple("Point", "x y") 
ROI = namedtuple("ROI", "point1 point2 point3 ... pointN") 
roi = ROI(Point(10, 20), Point(11, 21), ...) 

Эти случаи, то на самом деле держат значения, названные атрибуты возвращают:

roi.point1.x # 10 
roi.point2.y # 21 

Обратите внимание, что в соответствии с руководством по стилю Python Я дал атрибуты имен нижнего регистра ROI.

Я бы не использовал именованный кортеж, чтобы производить пронумерованные имена. Я бы просто использовать обычный кортеж и использовать индексацию:

roi = (Point(10, 20), Point(11, 21), ...) 
roi[0].x # 10 
roi[1].y # 21 

Если у вас есть последовательность (x, y) кортежей уже, вы можете произвести ваши ROI с помощью выражения генератора и namedtuple._make() class method:

points = [(10, 20), (11, 21), ...] 
roi = ROI._make(Point(*p) for p in points) 

создает новый экземпляр Point() для каждого кортежа в points и один новый экземпляр ROI, содержащий все экземпляры Point().