Есть ли преимущества использования метода @static?

Мне было интересно, используете ли вы @staticmethod decorator в своем коде.

Лично я не использую его, так как требуется больше писем для записи @staticmethod, затем self.

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

Или, может быть, я должен начать использовать декоратор @staticmethod?

Ответ 1

Использовать ли @staticmethod или нет, зависит от того, чего вы хотите достичь. Игнорирование декоратора, потому что есть больше типа, это довольно глупая причина (без обид!) И указывает, что вы не поняли концепцию статического метода в Python!

Статические методы не зависят от класса и любого экземпляра класса. Они используют только область класса как пространство имен. Если вы опустите декоратор @staticmethod, вы создаете метод экземпляра, который нельзя использовать без создания экземпляра.

Вот очень простой класс Foo:

>>> class Foo(object):
...    @staticmethod
...    def foo():
...       print 'foo'
...
...    def bar(self):
...       print 'bar'

Теперь Foo.foo() - это статический метод, который можно вызвать напрямую:

>>> Foo.foo()
foo

Foo.bar(), с другой стороны, это метод экземпляра, который может быть вызван только из экземпляров (объектов) Foo:

>>> Foo.bar()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unbound method foo() must be called with Foo instance as first argument (got nothing instead)
>>> foo = Foo()
>>> foo.bar()
bar

Чтобы ответить на ваш вопрос: если вы хотите определить статический метод, используйте @staticmethod. В противном случае, не делайте.

Если у вас есть метод, который не использует self, и поэтому может быть записан как статический метод, спросите себя: хотите ли вы когда-нибудь получить доступ к этой функции извне без экземпляра? В большинстве случаев ответ будет: Нет.

Ответ 2

@staticmethod Декоратор позволяет вам печатать и улучшать читаемость.

class Example:
    @staticmethod
    def some_method():
        return

совпадает с:

class Example:
    def some_method():
        return
    some_method = staticmethod(some_method)

Я думаю, вы можете быть смущены тем, что статический метод находится в Python, поскольку терминология отличается от других языков. Обычный метод "привязан" к экземпляру (self), метод класса "привязан" к классу (cls), а статический метод вообще не "привязан" (и не может получить доступ к экземпляру или классу атрибуты.

См:

Ответ 3

Предположим, что мы хотим определить метод abs в классе Math, тогда у нас есть два варианта:

class Math():
    def abs(n):
        if n>0:
            return n
        else:
            return -n

class Math2():
    @staticmethod
    def abs(n):
        if n>0:
            return n
        else:
            return -n

В Python2:

>>> Math.abs(-2)
TypeError: unbound method abs() must be called with Math instance as 
first argument (got int instance instead)

>>>Math().abs(-2)
TypeError: abs() takes exactly 1 argument (2 given)

>>> Math2.abs(-2)
2

>>> Math2().abs(-2)
2

python2 автоматически принимает Math().abs(-2) как Math().abs(self,-2), поэтому вам нужно использовать @staticmethod.

В Python3

>>>Math.abs(-3)
3

>>>Math().abs(-3)
TypeError: abs() takes 1 positional argument but 2 were given

>>>Math2.abs(-3)
3

>>>Math2().abs(-3)
3

В python3 вы можете использовать classname.method() без статического метода, но он будет поднимать TypeError, когда кто-то пытается использовать instance.method().