Я работал над очень плотным набором вычислений. Это все для поддержки конкретной проблемы c, которая у меня есть.
Но природа проблемы не отличается от этой. Предположим, я разработал класс Matrix, который имеет механизм для реализации матриц. Предполагается, что для создания экземпляра потребуется список списков, которые будут матричными записями.
Теперь я хочу предоставить метод умножения. У меня есть два варианта. Во-первых, я мог бы определить метод следующим образом:
class Matrix():
def __init__(self, entries)
# do the obvious here
return
def determinant(self):
# again, do the obvious here
return result_of_calcs
def multiply(self, b):
# again do the obvious here
return
Если я сделаю это, сигнатура вызова для двух объектов матрицы, a и b, будет
a.multiply(b)...
Другой выбор: @staticmethod. Тогда определение выглядит так:
@staticethod
def multiply(a,b):
# do the obvious thing.
Теперь подпись вызова:
z = multiply(a,b)
Мне неясно, когда один лучше другого. Отдельно стоящая функция не является частью определения класса, но кого это волнует? он выполняет свою работу, и поскольку Python позволяет ссылаться «на объект» извне, кажется, что он может делать все. На практике они (класс и метод) окажутся в одном модуле, поэтому они по крайней мере связаны между собой.
С другой стороны, мое понимание подхода @staticmethod состоит в том, что функция теперь является частью определения класса (он определяет один из методов), но метод не передает "self". В некотором смысле это хорошо, потому что сигнатура вызова выглядит намного лучше:
z = multiply(a,b)
и функция может получить доступ ко всем методам и атрибутам экземпляров.
Это правильный способ просмотра? Есть ли веские причины сделать то или другое? Чем они не эквивалентны?