Выбор типа метода зависит от других факторов.
У вас есть два случая. В первом случае метод должен быть частью интерфейса класса, например. он должен вызываться пользователями, или он должен переопределяться в подклассах, или он использует информацию в себе, или вполне вероятно, что в будущей версии программного обеспечения вам может понадобиться что-то из этого.
В этом первом случае вы часто использовали бы либо обычный метод (это когда метод относится к экземплярам, а не к классу), либо classmethod
(когда метод относится к классу, например, это альтернативный конструктор, метод для обнаружение признаков класса и т. д.). В обоих случаях вы можете использовать staticmethod
вместо этого, если метод не использует информацию из класса/экземпляра, но вы ничего не получаете от этого. И это также нарушило бы вашу способность делать cls.method(instance, *args)
, что уже слишком много, чтобы ничего не получить.
Второй случай — когда метод никаким образом не является частью класса. Тогда вообще целесообразно использовать функцию — метод на самом деле не является частью интерфейса, поэтому ему там не место. Ваш пример кажется именно таким, если только вы не хотите переопределить калькулятор дерева/денег в подклассах, но это во многом зависит от того, что вы с ним делаете.
Особым случаем являются приватные методы — тогда вы можете захотеть использовать метод, даже если он на самом деле не связан с классом, приватные методы не являются частью интерфейса, поэтому не имеет значения, где вы их поместите. Использование staticmethod
по-прежнему не дает вам многого, но и нет никаких причин не использовать его.
На самом деле есть один случай, когда staticmethod
очень полезен — когда вы помещаете в класс внешние функции (или другие объекты).
class Foo(object):
trees2money = staticmethod(calculators.trees2money)
foo = staticmethod(calculators.bar)
Но когда у вас есть статическое определение класса, это не очень хорошо, потому что вместо этого вы всегда можете сделать следующее.
class Foo(object):
def trees2money(self, trees):
"""Calculator for trees2money, you can override when subclassing"""
return calculators.trees2money(trees)
@property
def foo(self):
"""The foo of the object"""
return calculators.bar
Это дает вам лучшее представление о том, что делают эти объекты при чтении исходного кода, и даже позволяет добавлять документацию. Но это все равно может пригодиться, когда вы создаете классы динамически или добавляете их в метакласс (создавать метод-оболочку вручную не очень удобно).
person
Rosh Oxymoron
schedule
06.03.2011
@staticmethod
, потому что все, что вы хотите сделать с помощью статического метода, вероятно, должно быть сделано с помощью свободной функции или метода класса. - person   schedule 06.03.2011