← Назад к вопросам
Какие аргументы принимает метод @staticmethod?
1.8 Middle🔥 131 комментариев
#Python Core
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Аргументы метода @staticmethod в Python
Метод, украшенный @staticmethod, не получает автоматически никаких аргументов (ни self, ни cls). Он принимает только те аргументы, которые явно передаёт вызывающий код.
1. Основное отличие от обычных методов
class Calculator:
# Обычный метод (instance method)
def add(self, a, b):
# self - автоматический аргумент
return a + b
# Метод класса
@classmethod
def create_from_string(cls, string_repr):
# cls - автоматический аргумент
return cls()
# Статический метод
@staticmethod
def multiply(a, b):
# БЕЗ self, БЕЗ cls
return a * b
# Вызовы
calc = Calculator()
# Обычный метод - передаём только (a, b)
calc.add(5, 3) # OK: self передаётся автоматически
# Метод класса - передаём то же, что объявили
Calculator.create_from_string("5") # OK: cls передаётся автоматически
# Статический метод - передаём ровно то, что объявили
Calculator.multiply(5, 3) # OK: аргумента нет
Calculator.multiply(5, 3, "extra") # ERROR: неожиданный аргумент
2. Сигнатура @staticmethod
class Example:
# Без аргументов
@staticmethod
def no_args():
return "No arguments"
# С позиционными аргументами
@staticmethod
def with_args(a, b, c):
return a + b + c
# С именованными аргументами
@staticmethod
def with_kwargs(name, age=None, city=None):
return f"{name}, {age}, {city}"
# С *args и **kwargs
@staticmethod
def with_all_args(*args, **kwargs):
return args, kwargs
# Вызовы
Example.no_args() # OK
Example.with_args(1, 2, 3) # OK: 3
Example.with_kwargs("John", age=30) # OK
Example.with_all_args(1, 2, x=3, y=4) # OK: ((1, 2), {'x': 3, 'y': 4})
3. Важное: нельзя передавать self или cls
class MyClass:
@staticmethod
def static_method(self, a): # ❌ ОШИБКА в декларации
return a
# Python будет воспринимать self как обычный параметр!
# Вызов будет требовать обоих аргументов
MyClass.static_method("first_arg", "second_arg") # OK
# Но это не рекомендуется, так как нарушает конвенцию
4. Сравнение трёх типов методов
class Demo:
class_variable = "I am class variable"
# INSTANCE METHOD
def instance_method(self, x):
print(f"self: {self}")
print(f"x: {x}")
print(f"class_variable: {self.class_variable}")
# CLASS METHOD
@classmethod
def class_method(cls, x):
print(f"cls: {cls}")
print(f"x: {x}")
print(f"class_variable: {cls.class_variable}")
# STATIC METHOD
@staticmethod
def static_method(x):
print(f"x: {x}")
# Нет доступа к self или cls!
# print(f"class_variable: {class_variable}") # NameError!
# Вызовы и сигнатуры
obj = Demo()
# instance_method(self, x) -> вызываем с (x)
obj.instance_method("value") # self = obj
Demo.instance_method(obj, "value") # явная передача self
# class_method(cls, x) -> вызываем с (x)
obj.class_method("value") # cls = Demo
Demo.class_method("value") # cls = Demo (то же самое)
# static_method(x) -> вызываем с (x)
obj.static_method("value") # просто функция
Demo.static_method("value") # просто функция
5. Практические примеры использования
import math
from datetime import datetime
from typing import List
class MathUtils:
"""Утилиты для математических операций"""
@staticmethod
def distance(x1: float, y1: float, x2: float, y2: float) -> float:
"""Евклидово расстояние между двумя точками"""
return math.sqrt((x2 - x1)**2 + (y2 - y1)**2)
@staticmethod
def gcd(a: int, b: int) -> int:
"""НОД двух чисел"""
while b:
a, b = b, a % b
return a
@staticmethod
def is_prime(n: int) -> bool:
"""Проверка простоты числа"""
if n < 2:
return False
for i in range(2, int(math.sqrt(n)) + 1):
if n % i == 0:
return False
return True
class DateUtils:
"""Утилиты для работы с датами"""
@staticmethod
def days_between(date1: datetime, date2: datetime) -> int:
"""Количество дней между двумя датами"""
return abs((date2 - date1).days)
@staticmethod
def is_leap_year(year: int) -> bool:
"""Проверка високосного года"""
return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)
# Использование
print(MathUtils.distance(0, 0, 3, 4)) # 5.0
print(MathUtils.gcd(48, 18)) # 6
print(MathUtils.is_prime(17)) # True
print(DateUtils.is_leap_year(2024)) # True
6. Когда использовать @staticmethod
# ✓ ИСПОЛЬЗУЙ @staticmethod когда:
# 1. Утилиты, которые не зависят от состояния класса/инстанса
@staticmethod
def format_currency(amount: float, currency: str = "USD") -> str:
return f"{currency} {amount:.2f}"
# 2. Вспомогательные функции
@staticmethod
def validate_email(email: str) -> bool:
import re
pattern = r'^[\w\.-]+@[\w\.-]+\.\w+$'
return re.match(pattern, email) is not None
# 3. Функции, логически принадлежащие классу
class FileHandler:
@staticmethod
def read_file(path: str) -> str:
with open(path, 'r') as f:
return f.read()
@staticmethod
def write_file(path: str, content: str) -> None:
with open(path, 'w') as f:
f.write(content)
# ✗ НЕ ИСПОЛЬЗУЙ @staticmethod когда:
# 1. Нужен доступ к состоянию инстанса
class User:
def __init__(self, name):
self.name = name
# ❌ НЕПРАВИЛЬНО - нужен self
@staticmethod
def greet(greeting="Hello"):
return f"{greeting}, {self.name}" # NameError!
# ✓ ПРАВИЛЬНО
def greet(self, greeting="Hello"):
return f"{greeting}, {self.name}"
# 2. Нужна логика создания инстанса
class Person:
# ✗ НЕПРАВИЛЬНО - используй @classmethod
@staticmethod
def from_string(data: str):
name, age = data.split(',')
return Person(name, int(age)) # NameError: Person не определён?
# ✓ ПРАВИЛЬНО
@classmethod
def from_string(cls, data: str):
name, age = data.split(',')
return cls(name, int(age)) # используем cls
7. Декоратор @staticmethod внутри
# @staticmethod возвращает дескриптор
class MyDescriptor:
def __init__(self, func):
self.func = func
def __get__(self, obj, objtype=None):
# Просто возвращаем функцию как есть
return self.func
# Упрощённо, @staticmethod работает примерно так
class Example:
@staticmethod
def my_static(x):
return x * 2
# Эквивалентно
class Example2:
def my_static(x):
return x * 2
my_static = staticmethod(my_static)
# Обе работают одинаково
print(Example.my_static(5)) # 10
print(Example2.my_static(5)) # 10
Резюме
| Аспект | instance | @classmethod | @staticmethod |
|---|---|---|---|
| Первый аргумент | self | cls | нет |
| Может вызвать на объекте | ✓ | ✓ | ✓ |
| Может вызвать на классе | ✗ | ✓ | ✓ |
| Доступ к self | ✓ | ✗ | ✗ |
| Доступ к cls | ✗ | ✓ | ✗ |
| Создание инстансов | ✗ | ✓ | ✗ |
| Утилиты/хелперы | ✗ | ✗ | ✓ |
Главное: @staticmethod не получает автоматических аргументов и работает как обычная функция, логически объединённая с классом.