(заголовок и содержание обновляются после прочтения ответа Алекса)
В целом, я считаю, что считается плохой формой (непифонической) для функции, которая иногда возвращает итеративный, а иногда и единственный элемент в зависимости от его параметров.
Например, struct.unpack
всегда возвращает кортеж, даже если он содержит только один элемент.
Я пытаюсь завершить API для модуля, и у меня есть несколько функций, которые могут принимать один или несколько параметров (через *args
), например:
a = s.read(10) # reads 10 bits and returns a single item
b, c = s.read(5, 5) # reads 5 bits twice and returns a list of two items.
Таким образом, он возвращает один элемент, если есть только один параметр, в противном случае он возвращает список. Теперь я думаю, что это нормально и совсем не смущает, но я подозреваю, что другие могут не согласиться.
Самым распространенным вариантом использования этих функций может быть возвращение только одного элемента, поэтому всегда возвращающийся список (или кортеж) кажется неправильным:
a, = s.read(10) # Prone to bugs when people forget to unpack the object
a = s.read(10)[0] # Ugly and it's not clear only one item is being returned
Другой вариант - две функции:
a = s.read(10)
b, c = s.read_list(5, 5)
это нормально, но это загромождает API и требует от пользователя запоминания в два раза больше функций без добавления какого-либо значения.
Итак, мой вопрос: Иногда возвращает итеративный, а иногда один элемент, сбивающий с толку и непифитический? Если да, то какой вариант лучше?
Обновление : я думаю, что общий консенсус заключается в том, что очень непослушно иногда возвращать итеративное. Я думаю, что лучшим вариантом для большинства случаев было бы всегда возвращать итерируемое, даже если оно содержало только один элемент.
Сказав, что для моего конкретного случая, я думаю, что я пойду на разделение на две функции (read(item)
/ readlist(*items)
), причина в том, что я думаю, что случай с одним элементом будет происходить гораздо чаще, чем случай нескольких элементов, что упрощает использование, а изменение API менее проблематично для пользователей.
Спасибо всем.