Вызов статического метода python

Методы класса (classmethod) и статические методы (staticmethod)

Мы продолжаем тему методов в ООП. До сих пор мы с вами определяли методы просто как функции внутри класса, например:

class Vector: def __init__(self, x, y): self.x = x self.y = y def get_coord(self): return self.x, self.y

И у каждого такого метода, как правило, первым идет параметр self – ссылка на экземпляр класса, из которого метод был вызван:

v = Vector(10, 20) coord = v.get_coord() print(coord)

В данном случае, при вызове метода get_coord () параметр self будет вести на объект v класса Vector. Об этом мы с вами уже говорили. Также отмечали, что при вызове такого метода напрямую из класса нужно явно указывать первый аргумент self:

Так вот, в Python помимо таких «стандартных» методов можно задавать методы уровня класса и статические методы с помощью встроенных декораторов:

@classmethod и @staticmethod

Давайте я поясню на простом примере, что они значат. Добавим в наш класс Vector два атрибута:

class Vector: MIN_COORD = 0 MAX_COORD = 100 .
@classmethod def validate(cls, arg): return cls.MIN_COORD  arg  cls.MAX_COORD

который проверяет, попадает ли значение arg в диапазон [MIN_COORD; MAX_COORD]. Обратите внимание, у методов класса (когда мы используем декоратор classmethod) первым параметром идет cls – ссылка на класс, а не self – ссылка на объект класса. Это означает, что данный метод может обращаться только к атрибутам текущего класса, но не к локальным свойствам его экземпляров. Мало того, этот метод можно теперь напрямую вызывать из класса, не передавая ссылку на экземпляр, как это было при вызове обычных методов через класс:

res = Vector.validate(5) print(res)

Здесь пользователь класса Vector может совершенно спокойно вызывать метод validate(), не создавая никаких объектов. Но «платой» за это является ограниченность метода: он может работать только с атрибутами класса, но не объекта, что, в общем то, естественно, так как у него изначально нет ссылки на объект. Во всем остальном этот метод работает абсолютно также, как и любой другой метод, объявленный в классе.

Давайте мы им воспользуемся и вызовем внутри класса для проверки корректности координат x, y:

def __init__(self, x, y): self.x = self.y = 0 if Vector.validate(x) and Vector.validate(y): self.x = x self.y = y

Обратите внимание, мы здесь обращаемся к методу класса через пространство имен Vector. Но также можем прописать и self:

if self.validate(x) and self.validate(y):

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

Наконец, третий тип методов – статические методы, определяются декоратором @staticmethod. Это методы, которые не имеют доступа ни к атрибутам класса, ни к атрибутам его экземпляров, то есть, некая независимая, самостоятельная функция, объявленная внутри класса. Обычно, это делают для удобства, т.к. их функционал так или иначе связан с тематикой класса.

Например, в нашем классе Vector можно объявить такой статический метод, который бы вычислял квадратичную норму вектора (длину вектора в квадрате):

@staticmethod def norm2(x, y): return x*x + y*y

Здесь нет никаких скрытых параметров, которые бы автоматически заполнялись интерпретатором языка. Только те, что мы прописываем сами. Я указал два параметра x, y, по которым вычисляется квадрат длины радиус-вектора. То есть, это некая вспомогательная, сервисная функция, связанная с векторами, для вычисления квадратичной нормы любого радиус-вектора. Воспользоваться этим методом можно как вне класса:

def __init__(self, x, y): self.x = self.y = 0 if self.validate(x) and self.validate(y): self.x = x self.y = y print(Vector.norm2(self.x, self.y))

Либо, также обратиться к этому методу через self:

print(self.norm2(self.x, self.y))

Подведем итог различных типов методов в классах. Обычные методы, как правило, вызываются из экземпляров классов и работают с атрибутами экземпляров и атрибутами классов. Методы классов обычно вызываются через класс, реже через его экземпляры и имеют доступ только к атрибутам самого класса, в котором объявлены. Наконец, статические методы – это совершенно изолированные функции, которые работают только с параметрами, прописанными в ней самой и не имеют доступа к атрибутам класса или его экземпляров.

Поэтому, если вам нужен метод, который работает с атрибутами объектов класса, то это обычное определение функций внутри класса с первым параметром self. Если метод работает только с атрибутами класса, то возможно, имеет смысл его определить как метод класса и тогда можно будет вызывать без ссылки на объект этого класса. Третий тип, статические методы часто определяют как вспомогательные, сервисные, связанные с логикой работы самого класса.

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

Видео по теме

Концепция ООП простыми словами

Источник

Статический метод Python

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

Таким образом, статические методы в Python могут использоваться для выполнения операций, не требующих доступа к экземпляру класса или его атрибутам, то есть, по сути, они являются вспомогательными функциями. Чтобы было понятнее, о чём речь, перейдем сразу к практике.

Пример №1

Представим, что у нас есть класс MathUtils , который содержит статический метод для вычисления факториала:

class MathUtils: 
@staticmethod
def factorial(n):
if n == 0:
return 1
else:
return n * MathUtils.factorial(n-1)
print(MathUtils.factorial(5))
120

Получили факториал 5, то есть 120. Здесь статический метод factorial не использует никакие атрибуты экземпляра класса, а только входной аргумент n . И мы вызвали его, используя синтаксис MathUtils.factorial(n) и не создавая экземпляр класса MathUtils .

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

Пример №2

Допустим, у нас есть модуль StringUtils , содержащий статический метод для проверки, является ли строка палиндромом. Пишем такой код:

def is_palindrome(string): 
return string == string[::-1]

Здесь функция is_palindrome не связана с каким-либо экземпляром класса или объектом модуля, поэтому мы можем использовать декоратор @staticmethod для объявления ее как статической. Для этого расширим наш код таким образом:

class StringUtils: 
@staticmethod
def is_palindrome(string):
return string == string[::-1]

Далее введем для проверки:

print(StringUtils.is_palindrome("топот"))
True
print(StringUtils.is_palindrome("топор"))
False

Всё верно, первое слово является палиндромом, поэтому интерпретатор вывел True , а второе нет, и мы получили False .

Таким образом, мы можем вызвать метод is_palindrome через класс StringUtils , используя синтаксис StringUtils.is_palindrome(string) вместо того, чтобы импортировать функцию is_palindrome и вызывать ее напрямую.

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

Пример №3

Рассмотрим еще один пример. Допустим, у нас есть класс Person , имеющий атрибут age и статический метод is_adult , проверяющий значение на соответствие возрасту совершеннолетия:

class Person: 
def __init__(self, age):
self.age = age

@staticmethod
def is_adult(age):
return age >= 18

Далее давайте создадим переменную age со значением 21, вызовем статический метод is_adult из класса Person с этим значением и сохраним его результат в переменную is_adult , вот так:

age = 21
is_adult = Person.is_adult(age)

Теперь для проверки давайте введем:

Поскольку возраст соответствует заданному в статическом методе условию, мы получили True . В примере выше статический метод is_adult принимает аргумент age , но не имеет доступа к атрибуту age экземпляра класса Person , выступая в качестве вспомогательной функции.

Подведем итоги

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

Источник

Читайте также:  Hibernate spring java configuration
Оцените статью