Мне не нравятся функции Python, которые принимают два и более итераций Это хорошая идея? - PullRequest
3 голосов
/ 15 мая 2010

Этот вопрос возник при просмотре этого вопроса :

def fringe8((px, py), (x1, y1, x2, y2)):

Лично это была одна из моих любимых мозгов, чтобы увидеть функцию, которая принимает два аргумента с итерациями с фиксированным числом (как кортеж) или два или более словарей (как в Дробовик API ). Его просто сложно использовать из-за многословности и двойных скобок.

Разве это не было бы лучше:

>>> class Point(object):
...     def __init__(self, x, y):
...         self.x = x
...         self.y = y
...     
>>> class Rect(object):
...     def __init__(self, x1, y1, x2, y2):
...         self.x1 = x1
...         self.y1 = y1
...         self.x2 = x2
...         self.y2 = y2
...     
>>> def fringe8(point, rect):
...     # ...
...
>>>
>>> point = Point(2, 2)
>>> rect = Rect(1, 1, 3, 3)
>>>
>>> fringe8(point, rect)

Есть ли ситуация, когда использование двух или более итеративных аргументов оправдано? Очевидно, что стандартной itertools библиотеке Python это необходимо, но я не вижу ее привлекательной в поддерживаемом, гибком дизайне кода.

Ответы [ 2 ]

7 голосов
/ 15 мая 2010

Синтаксис def с распаковкой, как

def fringe8((px, py), (x1, y1, x2, y2)):

отсутствует в Python 3 - это означает, что Гвидо счел это ошибкой проектирования или, по крайней мере, необоснованным осложнением. Именованные кортежи могут быть даже лучше, чем специализированные классы для уточняющей цели, которую вы предлагаете.

Однако, иметь функции, которые принимают несколько итеративных аргументов, просто прекрасно - itertools, очевидно, не может инкапсулировать каждую многократную манипуляцию, которая может понадобиться вашим приложениям, конечно же! Думая о повторяемости как о «потоке» (возможно, неограниченном), существует огромное количество способов, которыми вы можете захотеть «объединить» несколько потоков в один, например (например, подумайте о потоках, которые, как известно, отсортированы и вы можете захотеть построить пересечение или объединение с удалением дубликатов и т. д. и т. п. или без них).

Почему когда-либо нужно искажать дизайн API, чтобы подчиняться совершенно произвольному запрету на наличие не более одной итерации на сигнатуру функции?!

1 голос
/ 15 мая 2010

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

Пока вы думаете о том, что у вас есть несколько итераций, я не вижу в этом проблемы. Некоторые функции действительно требуют нескольких списков (см. Встроенный zip). Но я думаю, что приведенный вами пример - это случай, когда кортежи используются, потому что это кажется более простым, но, возможно, не таким ясным.

...