Каково преимущество использования статических методов в Python?

Я столкнулся с несвязанной ошибкой метода в Python с кодом

class Sample(object):
'''This class defines various methods related to the sample'''

    def drawSample(samplesize,List):
        sample=random.sample(List,samplesize)
        return sample

Choices=range(100)
print Sample.drawSample(5,Choices)

После того, чтобы читать много полезных сообщений здесь, я изобразил, как я мог добавить @staticmethod выше для получения работы кода. Я - новичок Python. Кто-то может объяснить, почему можно было бы хотеть определить статические методы? Или, почему все методы не определяются как статические методы?

73
задан nbro 2 October 2019 в 16:44
поделиться

6 ответов

Статические методы имеют ограниченное использование, потому что у них нет доступа к атрибутам экземпляра класса (как у обычного метода), и они не не имеют доступа к атрибутам самого класса (как у метода класса).

Таким образом, они бесполезны для повседневных методов.

Однако они могут быть полезны для группировки некоторой полезной функции вместе с классом - например, простое преобразование из одного типа в другой - для которого не требуется доступ к какой-либо информации, кроме предоставленных параметров (и, возможно, некоторых атрибутов, глобальных для модуля).

Их можно было бы поместить вне класса, но сгруппировать их внутри class может иметь смысл там, где они применимы только там.

Вы также можете ссылаться на метод через экземпляр или класс, а не через имя модуля, что может помочь читателю понять, к какому экземпляру относится метод.

102
ответ дан 24 November 2019 в 12:05
поделиться

Когда вы вызываете объект функции из экземпляра объекта, он становится «связанным методом» и получает сам объект экземпляра, переданный в качестве первого аргумента.

Когда вы вызываете объект classmethod (который является оболочкой для объекта функции) в экземпляре объекта, класс объекта экземпляра передается в качестве первого аргумента.

Когда вы вызываете объект staticmethod (который является оболочкой для объекта функции), неявный первый аргумент не используется.

class Foo(object):

    def bar(*args):
        print args

    @classmethod
    def baaz(*args):
        print args

    @staticmethod
    def quux(*args):
        print args

>>> foo = Foo()

>>> Foo.bar(1,2,3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unbound method bar() must be called with Foo instance as first argument (got int instance instead)
>>> Foo.baaz(1,2,3)
(<class 'Foo'>, 1, 2, 3)
>>> Foo.quux(1,2,3)
(1, 2, 3)

>>> foo.bar(1,2,3)
(<Foo object at 0x1004a4510>, 1, 2, 3)
>>> foo.baaz(1,2,3)
(<class 'Foo'>, 1, 2, 3)
>>> foo.quux(1,2,3)
(1, 2, 3)
12
ответ дан 24 November 2019 в 12:05
поделиться

Зачем нужно определять статические методы ?

Предположим, у нас есть класс с именем Math , тогда

никто не захочет создавать объект ] class Math
, а затем вызвать на нем такие методы, как ceil и floor и fabs .

Поэтому мы делаем их статическими .

Например, выполнение

>> Math.floor(3.14)

намного лучше, чем

>> mymath = Math()
>> mymath.floor(3.14)

. Так что они в некотором роде полезны. Вам не нужно создавать экземпляр класса, чтобы использовать их.

Почему не все методы определены как статические ?

У них нет доступа к переменным экземпляра.

class Foo(object):
    def __init__(self):
        self.bar = 'bar'

    def too(self):
        print self.bar

    @staticmethod
    def foo():
        print self.bar

Foo().too() # works
Foo.foo() # doesn't work

Вот почему мы не делаем все методы статичными.

16
ответ дан 24 November 2019 в 12:05
поделиться

Это не совсем относится к вашему вопросу, но поскольку вы сказали, что вы новичок в python, возможно, это будет полезно, и никто другой не сказал об этом прямо.

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

def drawSample(samplesize,List):
    sample=random.sample(List,samplesize)
    return sample

Choices=range(100)
print drawSample(5,Choices)

Если у вас много связанных функций, вы можете сгруппировать их в модуль - т.е. поместить их все в один файл с именем sample. py, например; затем

import sample

Choices=range(100)
print sample.drawSample(5,Choices)

Или я бы добавил __init__ метод к классу и создал экземпляр с полезными методами:

class Sample(object):
'''This class defines various methods related to the sample'''

    def __init__(self, thelist):
        self.list = thelist

    def draw_sample(self, samplesize):
        sample=random.sample(self.list,samplesize)
        return sample

choices=Sample(range(100))
print choices.draw_sample(5)

(Я также изменил соглашения о регистре в приведенном примере, чтобы соответствовать стилю, рекомендованному в PEP 8.)

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

19
ответ дан 24 November 2019 в 12:05
поделиться

Статические методы почти не имеют смысла в Python. Вы используете либо методы экземпляра, либо методы класса.

def method(self, args):
    self.member = something

@classmethod
def method(cls, args):
    cls.member = something

@staticmethod
def method(args):
    MyClass.member = something
    # The above isn't really working
    # if you have a subclass
0
ответ дан 24 November 2019 в 12:05
поделиться

Статические методы хороши тем, что вам не нужно объявлять экземпляр объекта, которому принадлежит метод.

На сайте Python есть отличная документация по статическим методам:
http://docs.python.org/library/functions.html#staticmethod

3
ответ дан 24 November 2019 в 12:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: