Мне нужно работать с двумя объектами класса таким образом, чтобы вернуть третий объект того же класса, и я пытаюсь определить, как лучше это сделать: как независимую функцию, которая принимает два объекта и возвращает третий, или как метод, который принимает один другой объект и возвращает третий.
Для простого примера. Будет ли это:
from collections import namedtuple
class Point(namedtuple('Point', 'x y')):
__slots__ = ()
#Attached to class
def midpoint(self, otherpoint):
mx = (self.x + otherpoint.x) / 2.0
my = (self.y + otherpoint.y) / 2.0
return Point(mx, my)
a = Point(1.0, 2.0)
b = Point(2.0, 3.0)
print a.midpoint(b)
#Point(x=1.5, y=2.5)
или это:
from collections import namedtuple
class Point(namedtuple('Point', 'x y')):
__slots__ = ()
#not attached to class
#takes two point objects
def midpoint(p1, p2):
mx = (p1.x + p2.x) / 2.0
my = (p1.y + p2.y) / 2.0
return Point(mx, my)
a = Point(1.0, 2.0)
b = Point(2.0, 3.0)
print midpoint(a, b)
#Point(x=1.5, y=2.5)
и почему одно предпочтительнее другого?
Это кажется гораздо менее ясным, чем я ожидал, когда задавал вопрос.
В общем, кажется, что что-то вроде a.midpoint(b) не является предпочтительным, поскольку оно, похоже, отводит особое место той или иной точке в том, что на самом деле является симметричной функцией, которая возвращает совершенно новый экземпляр точки. Но, похоже, это в основном вопрос вкуса и стиля между чем-то вроде отдельно стоящей функции модуля или функции, прикрепленной к классу, но не предназначенной для вызова инстансом, такой как Point.midpoint(a, b).
Думаю, лично я стилистически склоняюсь к отдельно стоящим модульным функциям, но это может зависеть от обстоятельств. В случаях, когда функция определенно тесно связана с классом и есть риск загрязнения пространства имен или потенциальной путаницы, тогда создание функции класса, вероятно, имеет больше смысла.
Кроме того, несколько человек упомянули о необходимости сделать функцию более общей, возможно, реализовав дополнительные возможности класса для поддержки этого. В данном конкретном случае, когда речь идет о точках и медианах, это, вероятно, лучший подход. Он поддерживает полиморфизм и повторное использование кода и очень удобен для чтения. Однако во многих случаях это не сработает (например, в проекте, который вдохновил меня на этот вопрос), но точки и медианы показались мне лаконичным и понятным примером для иллюстрации вопроса.
Спасибо всем, это было познавательно.