Итератор по строки и столбцы


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

class ViewPlane(object):
    def __init__(self, resolution, pixel_size, gamma):
        self.resolution = resolution
        self.pixel_size = pixel_size
        self.gamma = gamma

    def __iter__(self):

        def genR():
            class IterRow(object):
                def __init__(self, plane, row):
                    self.plane = plane
                    self.row = row

                def __iter__(self):
                    def genC():
                        for column in xrange(self.plane.resolution[1]):
                            origin = (self.plane.pixel_size * 
                                       (column - self.plane.resolution[0] / 2.0 + 0.5)
                                        , 
                                        self.plane.pixel_size *
                                         (self.row - self.plane.resolution[1] / 2.0 + 0.5)
                                        , 
                                        100.0
                                     )
                            yield ( Ray(origin = origin, direction = (0.0,0.0,-1.0)), 
                                    (self.row,column)
                                )
                        return
                    return genC()
                def __str__(self):
                    return "Row iterator on row "+str(self.row)
            for row in xrange(self.resolution[0]):
                yield IterRow(self, row)

        return genR()

Вкратце: ViewPlane содержит пиксельный самолет. Этот класс реализует __ИТЭР__ , которая определяет и возвращает генератор функций. Этот генератор дает функция экземпляры внутреннего класса IterRow, который, в свою очередь, имеет __ИТЭР__ метод, который возвращает генератор перебора столбцов.

Я лично думаю, что это трудно понять, так что я был интересно, если есть пылесос стратегии для достижения такого же результата.



Комментарии
1 ответ

class Foo:
def __iter__(self):
def innergen():
yield something
return innergen()

Такой же как:

class Foo:
def __iter__(self):
yield something

Другими словами, нет необходимости определять генератор, просто дают значения.

Определение класса внутри метода просто служит, чтобы сделать вещи сложными и трудно читать. Определять класс вне метода.

Имея вернуться в конце функция не делает ничего и делает его похожим вы не знаете, что вы делаете. (Я не говорю, что нет, но всякий раз, когда вы включаете код с эфектом поднимает красный флаг. Ты думаешь, это что-то делать?)

Если вам действительно нужно, чтобы получить доступ к данные построчно я предлагаю уплощение итератора.

Стилистически, я предпочитаю разбить выражения, а затем пытается разбить их на несколько строк, как вы сделали. Я думаю, что это производит меньше помех.

Вот мой получившийся код:

class ViewPlane(object):
def __init__(self, resolution, pixel_size, gamma):
self.resolution = resolution
self.pixel_size = pixel_size
self.gamma = gamma

def __iter__(self):
for row in xrange(self.resolution[0]):
for column in xrange(self.resolution[1]):
origin_x = self.pixel_size * self.resolution[0] / 2.0 + 0.5
origin_y = self.pixel_size * self.resolution[1] / 2.0 + 0.5
origin = (origin_x, origin_y, 100)
ray = Ray(origin = origin, direction = (0.0, 0.0, -1.0) )

yield ray, (row, column)

Я не достаточно хорошо знаком с RayTracers знать, но я сомневаюсь, имея итератор по ViewPlane производить Рэй объектов. Итератор для получения содержимого объекта. Это реально содержится внутри ViewPlane? Или итератор производят координаты и пусть абонент построить Рэй объекты?

Редактировать

Вот версия, что не разогнуть итератора:

class ViewPlane(object):
def __init__(self, resolution, pixel_size, gamma):
self.resolution = resolution
self.pixel_size = pixel_size
self.gamma = gamma

def row_iter(self, row):
for column in xrange(self.resolution[1]):
origin_x = self.pixel_size * self.resolution[0] / 2.0 + 0.5
origin_y = self.pixel_size * self.resolution[1] / 2.0 + 0.5
origin = (origin_x, origin_y, 100)
ray = Ray(origin = origin, direction = (0.0, 0.0, -1.0) )

yield ray, (row, column)

def __iter__(self):
for row in xrange(self.resolution[0]):
yield self.row_iter(row)

4
ответ дан 16 мая 2011 в 06:05 Источник Поделиться