Зачем нужны статические методы python

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

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

Допустим, у нас есть модуль Python для служебных методов для строк, списков и кортежей.

Мы можем создавать статические методы в отдельных классах для лучшего понимания и простоты использования.

class ListUtils: @staticmethod def reverse(l): pass @staticmethod def clear(l): pass class StringUtils: @staticmethod def reverse(l): pass @staticmethod def upper(l): pass class TupleUtils: @staticmethod def reverse(t): pass @staticmethod def shuffle(t): pass

Если нам нужно перевернуть список, мы ListUtils.reverse() метод ListUtils.reverse() . Если нам нужно перетасовать элементы кортежа, мы TupleUtils.shuffle() статический метод TupleUtils.shuffle() .

Как создать статический метод в Python

1. Использование функции staticmethod()

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

class StringUtils: def to_uppercase(s): return str(s).upper() StringUtils.upper = staticmethod(StringUtils.to_uppercase) print(StringUtils.upper('Python')) # PYTHON

Если мы попытаемся вызвать метод to_uppercase() из объекта StringUtils, он вызовет ошибку, поскольку «метод принимает 1 позиционный аргумент, но было дано 2».

su = StringUtils() try: print(su.to_uppercase('Python')) except TypeError as te: print(te) # Output # to_uppercase() takes 1 positional argument but 2 were given

Однако мы можем вызвать метод to_uppercase() из ссылки на класс.

print(StringUtils.to_uppercase('Python')) # PYTHON

пример статического метода

2. Использование аннотации @staticmethod

Это рекомендуемый способ создания статического метода. Нам просто нужно аннотировать метод декоратором @staticmethod.

class MathUtils: @staticmethod def multiply(a, b): return a * b print(MathUtils.multiply(10, 5)) # 50

Staticmethod Декоратор Аннотация

Статический метод и метода класса — сравнение

  • Метод класса Python может получить доступ к переменным класса, но статический метод не может получить доступ к переменным класса.
  • Метод класса требует, чтобы первый формальный параметр был привязан к классу. Статический метод может присутствовать без каких-либо параметров.
  • Мы используем @classmethod для создания методов класса. Мы используем @staticmethod для создания статических методов.
class Test: x = 10 @classmethod def foo(cls): print(cls.x) @staticmethod def bar(): # Unresolved reference error for class variable x # print(x) pass

Сравнение статического метода и метода экземпляра

  • Метод экземпляра в классе может обращаться как к переменным экземпляра, так и к переменным класса. Статический не может получить доступ к переменным класса или переменным экземпляра.
  • Нам нужна «собственная переменная» в качестве формального параметра для метода экземпляра. В статическом такого ограничения нет.
  • Мы используем декоратор @staticmethod. Нам не нужны декораторы для создания функции экземпляра.
class Test: x = 10 def func(self): print(type(self)) print(self.x)

Преимущества

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

Источник

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

Источник

Объяснение @classmethod и @staticmethod в Python

Для новичков, изучающих объектно-ориентированное программирование на Python, очень важно хорошо разбираться в таких понятиях как classmethod и staticmethod для написания более оптимизированного и повторно используемого кода.

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

В этой статье мы разберем что это такое и какая между ними разница.

staticmethod в Python

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

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

class ClassName: @staticmethod def method_name(arg1, arg2, . ): .

Здесь мы используем декоратор @staticmethod для определения статического метода в Python. Вы можете заметить, что статический метод не принимает self в качестве первого аргумента для метода.

А теперь посмотрим на пример использования.

class Myclass(): @staticmethod def staticmethod(): print('static method called')

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

Хотя вызов метода из экземпляра класса тоже возможен.

my_obj = Myclass() my_obj.staticmethod()

Отлично, но когда полезны статические методы?

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

class Person(): @staticmethod def is_adult(age): if age > 18: return True else: return False

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

Classmethod в Python

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

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

class Class: @classmethod def method(cls, arg1, arg2, . ): .

В данному случае декоратор @classmethod используется для создания методов класса, и cls должен быть первым аргументом каждого метода класса.

class MyClass: @classmethod def classmethod(cls): print('Class method called')

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

Когда использовать classmethod?

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

Поэтому, если вы хотите получить доступ к свойству класса в целом, а не к свойству конкретного экземпляра этого класса, используйте classmethod.

class MyClass(): TOTAL_OBJECTS=0 def __init__(self): MyClass.TOTAL_OBJECTS = MyClass.TOTAL_OBJECTS+1 @classmethod def total_objects(cls): print("Total objects: ",cls.TOTAL_OBJECTS) # Создаем объекты my_obj1 = MyClass() my_obj2 = MyClass() my_obj3 = MyClass() # Вызываем classmethod MyClass.total_objects()

Теперь, если мы унаследуем этот класс в дочерний класс и объявим там переменную TOTAL_OBJECTS и вызовем метод класса из дочернего класса, он вернет общее количество объектов для дочернего класса.

class MyClass(): TOTAL_OBJECTS=0 def __init__(self): MyClass.TOTAL_OBJECTS = MyClass.TOTAL_OBJECTS+1 @classmethod def total_objects(cls): print("Total objects: ", cls.TOTAL_OBJECTS) # Создаем объекты родительского класса my_obj1 = MyClass() my_obj2 = MyClass() # Создаем дочерний класс class ChildClass(MyClass): TOTAL_OBJECTS=0 pass ChildClass.total_objects()

Заключение

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

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

Источник

Читайте также:  Python requests content decode
Оцените статью