Подтвердить что ты не робот

В чем преимущество использования статических методов в 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 выше, чтобы код работал. Я новичок в питоне. Может кто-нибудь объяснить, почему можно определить статические методы? Или, почему не все методы определены как статические методы?

4b9b3361

Ответ 1

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

Поэтому они не полезны для повседневных методов.

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

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

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

Ответ 2

Подробнее см. в этой статье.

TL; DR

1.It исключает использование аргумента self.

2. Это уменьшает использование памяти, потому что Python не должен создавать связанный метод для каждого объекта instiantiated:

>>>RandomClass().regular_method is RandomClass().regular_method
False
>>>RandomClass().static_method is RandomClass().static_method
True
>>>RandomClass.static_method is RandomClass().static_method
True

3.It улучшает читаемость кода, означая, что метод не зависит от состояния самого объекта.

4.It позволяет переопределить метод в том случае, если метод был определен на уровне модуля (то есть вне класса), подкласс не сможет переопределить этот метод.

Ответ 3

Это не совсем соответствует вашему актуальному вопросу, но, поскольку вы сказали, что вы новичок в 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 является то, что он не заставляет вас использовать классы для всего. Вы можете использовать их, только когда есть данные или состояние, которые должны быть связаны с методами, для чего предназначены классы. В противном случае вы можете использовать функции, для которых и предназначены функции.

Ответ 4

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

Предположим, что a class называется Math, тогда

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

Итак, мы делаем их static.

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

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

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

Ответ 5

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

Когда вы вызываете объект 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)

Ответ 6

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

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

Ответ 7

Поскольку функции пространств имен хороши (как указывалось ранее):

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

  • Когда я рефакторирую действительно гнилой код, я начинаю с попытки сделать как можно больше методов @staticmethod. Это позволяет мне затем извлечь эти методы в класс, хотя я согласен, что это редко что-то, что я использую, это помогло несколько раз.

Ответ 8

Статические методы практически не имеют причин для 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

Ответ 9

По моей оценке, нет единого выигрыша в производительности при использовании @staticmethod по сравнению с простым определением функции вне и отдельно от класса, в противном случае это было бы @staticmethod из.

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

Одна вещь, которую я иногда люблю делать, это помещать функциональность, которую мой класс использует внутри себя, в частные @staticmethod. Таким образом, я не загромождаю API, предоставляемый моим модулем, методами, которые никто, использующий мой модуль, никогда не должен видеть, не говоря уже о его использовании.