В чем преимущество использования статических методов в 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. Может кто-нибудь объяснить, почему нужно определить статические методы? Или, почему не все методы определены как статические методы?
9 ответов:
статические методы имеют ограниченное использование, потому что они не имеют доступа к атрибутам экземпляра класса (как это делает обычный метод), и они не имеют доступа к атрибутам самого класса (как это делает метод класса).
поэтому они не полезны для повседневных методов.
тем не менее, они могут быть полезны для группировки некоторых функций полезности вместе с классом - например, простое преобразование из одного типа в другой - что не требует доступа к любому информация помимо предоставленных параметров (и, возможно, некоторые атрибуты, глобальные для модуля.)
Они могут быть помещены вне класса, но группировка их внутри класса может иметь смысл там, где они применимы только там.
вы также можете ссылаться на метод через экземпляр или класс, а не имя модуля, что может помочь читателю понять, к какому экземпляру относится метод.
посмотреть в этой статье для подробного объяснения.
TL; DR
1.It исключает использование
Это не совсем к точке вашего фактического вопроса, но так как вы сказали, что вы новичок 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 является то, что он не заставляет вас использовать классы для всего. Вы можете использовать их только тогда, когда есть данные, которые должны быть связаны с методы, для чего и существуют классы. В противном случае вы можете использовать функции, для чего и предназначены функции.
когда вы вызываете объект функции из экземпляра объекта, он становится "связанным методом" и получает сам объект экземпляра передается в качестве первого аргумента.
когда вы называете
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)
почему нужно определять статические методы?
предположим, что у нас есть
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
вот почему мы не делаем все методы статическими.
статические методы хороши, потому что вам не нужно объявлять экземпляр объекта, к которому принадлежит метод.
на сайте python есть отличная документация по статическим методам здесь:
http://docs.python.org/library/functions.html#staticmethod
статические методы почти не имеют оснований быть в 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
потому что функции пространства имен хороши (как было указано ранее):
когда я хочу быть явными о методах, которые не изменяют состояние объекта, я использую статические методы. Это обескураживает людей в моей команде, чтобы начать изменять атрибуты объекта в этих методах.
когда я рефакторинг действительно гнилой код, я начинаю, пытаясь сделать как можно больше методов
@staticmethod
Как это возможно. Это позволяет мне извлечь эти методы в класс-хотя я согласен, это редко то, что я использую, это действительно было полезно несколько раз.
по моей оценке, нет ни одного производительность преимущества использования
@staticmethod
s по сравнению с просто определением функции вне и отдельно от класса это было бы иначе@staticmethod
of.единственное, что я бы сказал, что оправдывает их существование-это удобство. Статические методы распространены в других популярных языках программирования, так почему бы не python? Если вы хотите создать функцию с поведением, которое очень тесно связано с создаваемым классом это для того, но на самом деле он не получает доступ/не изменяет внутренние данные экземпляра класса таким образом, что оправдывает его концептуализацию как типичный метод этого класса, а затем хлопает a
@staticmethod
над ним и любой читающий ваш код сразу узнает много нового о природе метода и его отношении к классу.одна вещь, которую я иногда люблю делать, это разместить функциональность, которую мой класс использует внутренне много в private
@staticmethod
s. таким образом, я не загромождаю API выставленный моим модулем с методами, которые никто, используя мой модуль, никогда не должен был бы видеть, не говоря уже об использовании.