Независимая функция или метод

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


Для простого примера. Будет ли это:

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).

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

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

Спасибо всем, это было познавательно.

6
задан TimothyAWiseman 27 October 2011 в 17:25
поделиться