Зачем в питоне нужен @staticmethod
Есть класс printer . У него есть 2 метода, делающие одно и то же. Различие в том, что один из методов — с декоратором @staticmethod , а другой — без. Но я могу вызывать оба метода без создания экземпляра класса.
class printer(): ''' Тест @staticmethod ''' def not_static_print(self, text = 'Example Text'): print(text) @staticmethod def static_print(text = 'Example Text'): print(text) # Не создаю никаких экземпляров printer.not_static_print(None, 'Emm?') printer.static_print('Something like this.')
Просто для not_static_print() я указываю экземпляр, а точнее его отсутствие ( None ) Есть ли принципиальная разница в использовании этих методов?
Отслеживать
149k 12 12 золотых знаков 59 59 серебряных знаков 132 132 бронзовых знака
задан 6 авг 2018 в 17:19
Don2Quixote Don2Quixote
1,705 3 3 золотых знака 12 12 серебряных знаков 26 26 бронзовых знаков
p = printer() p.not_static_print(None, ‘Emm?’) а теперь попробуйте вызвать тот not_static_print с None первым аргументом 🙂
6 авг 2018 в 17:29
кст, в вашем примере у класса нет полей объекта и в not_static_print вы к ним не обращайтесь, а это будет возможно только через self , но если вы это сделайте и передадите None , то будет ошибка AttributeError: ‘NoneType’ object has no attribute . Вот для таких случаев и существуют статичные методы — они не могут работать с полями и методами объекта, но при этом их не сделали просто функциями, т.к. они логически относятся к данному классу / типу
Основы работы с @classmethod и @staticmethod в Python
Одним из основных принципов объектно-ориентированного программирования в Python является использование методов класса. Они позволяют управлять поведением класса и его экземпляров. В Python, как и в большинстве других языков, методы класса обычно привязаны к конкретному экземпляру этого класса и могут взаимодействовать с его атрибутами.
class MyClass: def __init__(self, param): self.param = param def print_param(self): print(self.param) my_instance = MyClass(5) my_instance.print_param() # Вывод: 5
Однако, иногда требуется создать метод, который не привязан к конкретному экземпляру, а относится ко всему классу в целом. Здесь на помощь приходят декораторы @classmethod и @staticmethod .
@classmethod
Декоратор @classmethod преобразует обычный метод в метод класса. Это значит, что он привязан к самому классу, а не к его экземплярам. Первым аргументом такого метода всегда является сам класс (обычно обозначается как cls ), а не экземпляр класса ( self ).
class MyClass: param = 5 @classmethod def print_param(cls): print(cls.param) MyClass.print_param() # Вывод: 5
Методы, отмеченные @classmethod , могут быть унаследованы и переопределены в подклассах, что дает большую гибкость при работе с наследованием.
@staticmethod
Еще одним видом методов класса в Python являются статические методы, которые отмечаются декоратором @staticmethod . Статические методы ведут себя как обычные функции, за исключением того, что они могут быть вызваны на уровне класса.
class MyClass: @staticmethod def print_hello(): print("Hello, world!") MyClass.print_hello() # Вывод: Hello, world!
Статические методы не имеют доступа ни к классу, ни к его экземплярам, поэтому они обычно используются для выполнения вспомогательных функций, которые не взаимодействуют с атрибутами класса.
Вывод
Методы класса и статические методы в Python — это мощные инструменты, которые позволяют управлять поведением классов и их экземпляров. Они помогают создавать более гибкий и модульный код, а также упрощают процесс наследования и переопределения методов.
Разница между @staticmethod и @classmethod в Python
Когда разработчики начинают использовать Python, они часто сталкиваются с декораторами @staticmethod и @classmethod. Оба этих декоратора служат для определения методов, которые не работают с экземплярами класса, но все же как-то связаны с классом.
Пример
Рассмотрим простой класс «Кошка» с методом «мяукать», который определен как статический метод.
class Cat: @staticmethod def meow(): return "Мяу!"
Так как «мяукать» является статическим методом, его можно вызывать без создания экземпляра класса.
print(Cat.meow()) # Выводит "Мяу!"
@staticmethod
Статический метод в Python — это метод, который принадлежит классу, а не экземпляру класса. Он не может модифицировать состояние класса или его экземпляров. Статические методы объявляются с помощью декоратора @staticmethod.
Преимущество статических методов в том, что они могут быть вызваны даже если нет объекта класса. Они также могут быть переопределены в подклассах.
@classmethod
Метод класса в Python — это метод, который привязан к классу, а не к его экземпляру. Он может изменять состояние класса, но не может изменять состояние конкретного экземпляра класса. Методы класса объявляются с помощью декоратора @classmethod.
Методы класса принимают ссылку на класс, который вызывает метод, в качестве первого аргумента (обычно именуемого cls). Их основное преимущество в том, что они могут быть наследованы и переопределены в подклассах.
Вывод
В целом, @staticmethod и @classmethod в Python служат для определения методов, которые не требуют доступа к экземпляру класса. Они оба полезны в разных ситуациях, и выбор между ними зависит от конкретных потребностей вашего кода. Если вам нужно работать с классом, а не с его экземпляром, используйте @classmethod. Если вам не нужен доступ ни к классу, ни к его экземплярам, используйте @staticmethod.
Декоратор staticmethod#
Статический метод — это метод, который не привязан к состоянию экземпляра или класса. Для создания статического метода используется декоратор staticmethod.
Преимущества использования staticmethod:
- Это подсказка для тех, кто читает код, которая указывает на то, что метод не зависит от состояния экземпляра класса.
Большинству методов для работы нужна ссылка на экземпляр, поэтому как первый аргумент используется self. Однако иногда бывают методы, которые никак не связаны с экземпляром и зависят только от аргументов. Как правило, в таком случае можно даже вынести метод из класса и сделать его функцией. Если же метод логически связан с работой класса, но работает одинаково независимо от состояния экземпляров, метод декорируют декоратором staticmethod, чтобы указать это явно.
import time from textfsm import clitable from base_ssh import BaseSSH class CiscoSSH(BaseSSH): def __init__(self, ip, username, password, enable_password, disable_paging=True): super().__init__(ip, username, password) self._ssh.send('enable\n') self._ssh.send(enable_password + '\n') if disable_paging: self._ssh.send('terminal length 0\n') time.sleep(1) self._ssh.recv(self._MAX_READ) self._mgmt_ip = None @staticmethod def _parse_show(command, command_output, index_file='index', templates='templates'): attributes = 'Command': command, 'Vendor': 'cisco_ios'> cli_table = clitable.CliTable(index_file, templates) cli_table.ParseCmd(command_output, attributes) return [dict(zip(cli_table.header, row)) for row in cli_table] def send_show_command(self, command, parse=True): command_output = super().send_show_command(command) if not parse: return command_output return self._parse_show(command, command_output)
In [6]: r1 = CiscoSSH('192.168.100.1', 'cisco', 'cisco', 'cisco') In [7]: r1.send_show_command('sh ip int br') Out[7]: ['intf': 'Ethernet0/0', 'address': '192.168.100.1', 'status': 'up', 'protocol': 'up'>, 'intf': 'Ethernet0/1', 'address': '192.168.200.1', 'status': 'up', 'protocol': 'up'>, 'intf': 'Ethernet0/2', 'address': '19.1.1.1', 'status': 'up', 'protocol': 'up'>, 'intf': 'Ethernet0/3', 'address': '192.168.230.1', 'status': 'up', 'protocol': 'up'>, 'intf': 'Loopback0', 'address': '10.4.4.4', 'status': 'up', 'protocol': 'up'>, 'intf': 'Loopback90', 'address': '90.1.1.1', 'status': 'up', 'protocol': 'up'>]