Возврат объекта или возврат кортежа

Я разрабатываю в python класс файлов, который может читать и записывать файл, содержащий список координат xyz. В моей программе у меня уже есть класс Coord3D для хранения координат xyz.

Мой вопрос относительно дизайна метода getCoordinate (index). Должен ли я возвращать кортеж поплавков или объект Coord3D?

В первом случае я получаю очень низкую связь, но тогда мне, вероятно, придется создавать экземпляр объекта Coord3D с полученными значениями, хотя и вне класса файла. Во втором случае у меня будет класс файлов, тесно связанный с классом Coord3D.

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


Изменить: чтобы напомнить ответы, которые я получил до сих пор, похоже, что нет четкого выбора. Было сказано (надлежащим образом), что python - это не Java, и вам не нужен специализированный класс для всего, потому что он вам нужен по языковой архитектуре. В моем случае, однако, у меня есть следующие условия:

  • Я работаю над библиотекой, где объект Coord3D используется как есть. Использование этого повысит согласованность моей библиотеки, поскольку типы данных будут одинаково использоваться.
  • Объект Coord3D имеет состояние и поведение. Действительно, объект Coord3D объединяет координаты и единицы в едином объекте. Операции между объектами Coord3D будут учитывать потенциально разные единицы и действовать соответственно.
  • Я могу поместить централизованный код управления в экземпляр класса Code3D, чтобы отказаться, например, от массивов длины 4 или не единиц. Если я использую кортеж, я не могу выполнить эту проверку. Более того, если метод принимает команду Coord3D, это гарантировано, что он хорошо сформирован заранее (вы можете быть жирным и проверить наличие isinstance или проверить интерфейс). Кортеж может содержать недопустимые данные. Хотя подход python к обработке ошибок выполняется там, где возникает проблема, класс, препятствующий мне иметь координату xyz, сделанную из трех строк, как-то полезен (исправьте меня, если не так, пожалуйста)

С другой стороны, использование кортежа имеет следующие преимущества:

  • Меньшее занятие ресурсами, весьма критичное в случае огромных
  • Упрощенная конструкция. Больше классов означает более сложный дизайн. Кортеж - это стандартный тип данных, который хорошо понимается и может быть легко распакован. Индивидуальный класс не является.
  • Используя кортеж, класс XYZFile полностью отделен от остальной библиотеки (поскольку он не использует объект Coord3D). Это означает, что он может быть повторно использован полностью как независимый объект.

дальнейшие комментарии очень приветствуются!

Ответ 1

Я задал себе тот же вопрос, хотя при этом делаю 2D-геометрию.

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

Ответ 2

Компромиссное решение: вместо класса сделайте Coord3D a namedtuple и верните, что: -)

Использование:

Coord3D = namedtuple('Coord3D', 'x y z')

def getCoordinate(index):
    # do stuff, creating variables x, y, z
    return Coord3D(x, y, z)

Возвращаемое значение может быть использовано точно как кортеж и имеет те же свойства скорости и памяти, что и вы не теряете никакой универсальности. Но вы можете также получить доступ к своим значениям по имени: если c является результатом getCoordinate(index), вы можете работать с c.x, c.y и т.д. Для повышения степени удобочитаемости.

(очевидно, это немного менее полезно, если ваш класс Coord3D также нуждается в других функциях)

[если вы не на python2.6, вы можете получить namedtuples из рецепт поваренной книги]

Ответ 3

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

# get the object
coord_obj = my_obj.getCoordinate(my_index)
# get the tuple (for example, via a property named "coords")
coord_tup = my_obj.getCoordinate(my_index).coords

Ответ 4

Более фундаментальный вопрос: "Почему у вас есть класс Coord3D?" Почему бы просто не использовать кортеж?

Общий совет, который большинство из нас дает Python n00bz, - "не изобретайте новые классы, пока вам не придется".

Имеет ли ваш метод Coord3D уникальные методы? Возможно, вам нужен новый класс. Или, может быть, вам нужны только некоторые функции, которые работают с кортежами.

Имеется ли у вашего координатора 3 переменное состояние? Вряд ли. Неизменяемый кортеж начинает выглядеть лучше, чем новый класс.

Ответ 5

Взгляните на Will McGugan Библиотека Gameobjects. У него есть Vector3 class, который может быть инициализирован другим объектом Vector3, кортежем, отдельными значениями float и т.д. Я думаю, что это ответит на ваш вопрос... плюс вы можете просто использовать свою библиотеку, поскольку она уже оптимизирована, и уже есть много полезных методов.

Ответ 6

Если он будет использоваться только в вашем приложении, и если вы все равно создадите экземпляр Coord3D со значениями, я просто верну экземпляр Coord3D, чтобы сэкономить ваши усилия. Если, однако, вы заинтересованы в создании этого портативного/общего, верните кортеж. В любом случае будет легко создать Coord3D, используя

c3d = Coord3D(*getCoordinate(index))

(если ваш конструктор Coord3D.__init__(self, x, y, z))

Ответ 7

Возвращение объекта будет лучшей практикой и даст вам лучший общий дизайн программного обеспечения. Я бы рекомендовал сделать это

Но помните, что создание/возвращение объекта потребует большего времени обработки. Это может изменить что-то, если вы сделаете эту операцию LOT, и в этом случае вам может понадобиться подумать об этом...