Возможно ли иметь статические методы в Python, которые я мог бы вызывать без инициализации класса, например:
ClassName.static_method()
источник
Возможно ли иметь статические методы в Python, которые я мог бы вызывать без инициализации класса, например:
ClassName.static_method()
Да, используя статический метод декоратор
class MyClass(object):
@staticmethod
def the_static_method(x):
print(x)
MyClass.the_static_method(2) # outputs 2
Обратите внимание, что некоторый код может использовать старый метод определения статического метода, используя staticmethod
как функцию, а не как декоратор. Это следует использовать, только если вы должны поддерживать древние версии Python (2.2 и 2.3)
class MyClass(object):
def the_static_method(x):
print(x)
the_static_method = staticmethod(the_static_method)
MyClass.the_static_method(2) # outputs 2
Это полностью идентично первому примеру (использующему @staticmethod
), только не использующему хороший синтаксис декоратора
Наконец, используйте staticmethod()
экономно! В Python очень мало ситуаций, когда необходимы статические методы, и я видел, как они использовались много раз, когда отдельная функция «верхнего уровня» была бы более понятной.
Ниже приводится дословно из документации :
Статический метод не получает неявный первый аргумент. Чтобы объявить статический метод, используйте эту идиому:
class C: @staticmethod def f(arg1, arg2, ...): ...
Форма @staticmethod является декоратором функции - подробности см. В описании определений функций в определениях функций .
Он может быть вызван либо в классе (например,
C.f()
), либо в экземпляре (например,C().f()
). Экземпляр игнорируется за исключением его класса.Статические методы в Python похожи на те, которые есть в Java или C ++. Для более продвинутой концепции см
classmethod()
.Для получения дополнительной информации о статических методах см. Документацию по стандартной иерархии типов в разделе Стандартная иерархия типов .
Новое в версии 2.2.
Изменено в версии 2.4: добавлен синтаксис функции декоратора.
@staticmethod
украшения или использовать указатель на функцию, когда вы можете просто избежать первогоself
параметра? Ну, для объектаa
вы не сможете вызыватьa.your_static_method()
, что разрешено на других языках, но это в любом случае считается плохой практикой, и компилятор всегда предупреждает об этомClassName.methodName()
, как если бы он был статическим, и тогдаself
метод не будет предоставлен. Как вы сказали, все еще можно будет также вызывать этот метод какClassInstance.methodName()
иself
будет предоставлен в качестве первого параметра, независимо от его имени.Я думаю, что Стивен на самом деле прав . Чтобы ответить на исходный вопрос, затем, чтобы настроить метод класса, просто предположите, что первый аргумент не будет вызывающим экземпляром, а затем убедитесь, что вы вызываете метод только из класса.
(Обратите внимание, что этот ответ относится к Python 3.x. В Python 2.x вы получите
TypeError
вызов метода для самого класса.)Например:
В этом коде метод rollCall предполагает, что первый аргумент не является экземпляром (как если бы он вызывался экземпляром, а не классом). Пока "rollCall" вызывается из класса, а не из экземпляра, код будет работать нормально. Если мы попытаемся вызвать "rollCall" из экземпляра, например:
однако это вызвало бы возникновение исключения, поскольку оно отправило бы два аргумента: себя и -1, а «rollCall» определен только для принятия одного аргумента.
Между прочим, rex.rollCall () отправит правильное количество аргументов, но также вызовет исключение, потому что теперь n будет представлять экземпляр Dog (т.е. rex), когда функция ожидает, что n будет числовым.
Вот где приходит украшение: если мы предшествуем методу rollCall
затем, явно указав, что метод является статическим, мы можем даже вызвать его из экземпляра. Сейчас же,
должно сработать. Вставка @staticmethod перед определением метода не позволяет экземпляру отправлять себя в качестве аргумента.
Вы можете убедиться в этом, попробовав следующий код с закомментированной строкой @staticmethod и без нее.
источник
TypeError: unbound method rollCall() must be called with Dog instance as first argument (got int instance instead)
T.my_static_method()
илиtype(my_t_instance).my_static_method()
, так как это понятнее и сразу делает очевидным, что я вызываю статический метод.Да, проверьте статический метод декоратора:
источник
Вам не нужно использовать
@staticmethod
декоратор. Просто объявите метод (не ожидающий параметра self) и вызовите его из класса. Декоратор существует только в том случае, если вы хотите иметь возможность вызывать его также из экземпляра (что не было тем, что вы хотели сделать)В основном вы просто используете функции, хотя ...
источник
class Dummy: def static1(): print "hello from static1" @staticmethod def static2(): print "hello from static2" Dummy.static2() Dummy.static1()
Вывод: привет из static2 Traceback <последний вызов последнего>: файл "ll.py", строка 46, в <module> Dummy.static1 () TypeError: метод unbound static1 () должен быть вызван с пустым экземпляром в качестве первого аргумента (вместо этого ничего не получил)self
в качестве первого аргумента, если вы не скажете, что нет. (см .: декоратор)self
ссылку соответствующим образом в зависимости от того, как он вызывается. Тестовый пример: pastebin.com/12DDV7DB .staticmethod
Декоратор позволяет вызвать функцию как класс и экземпляр (это решение не выполняется при вызове функции на примере).class C: def callme(): print('called'); C.callme()
Да, статические методы могут быть созданы следующим образом (хотя для Pythonic немного более важно использовать подчеркивание вместо CamelCase для методов):
Выше используется синтаксис декоратора. Этот синтаксис эквивалентен
Это можно использовать так же, как вы описали:
Встроенный пример статического метода
str.maketrans()
в Python 3, который был функцией вstring
модуле в Python 2.Другой вариант, который можно использовать при описании, заключается в том
classmethod
, что метод класса получает класс в качестве неявного первого аргумента, а в случае подкласса он получает подкласс в качестве неявного первого аргумента.Обратите внимание, что
cls
это не обязательное имя для первого аргумента, но большинство опытных программистов на Python сочтут, что это неправильно, если вы используете что-то еще.Они обычно используются в качестве альтернативных конструкторов.
Встроенный пример
dict.fromkeys()
:источник
Помимо особенностей поведения объектов статических методов , есть некоторая красота, с которой вы можете поразить их, когда речь заходит об организации кода на уровне модулей.
...
...
...
Теперь он становится немного более интуитивно понятным и самодокументируемым, в котором должны использоваться определенные компоненты, и он идеально подходит для именования отдельных тестовых случаев, а также имеет простой подход к тому, как тестовые модули отображаются на реальные тестируемые модули для пуристов. ,
Я часто считаю целесообразным применять этот подход к организации служебного кода проекта. Довольно часто люди сразу же спешат создать
utils
пакет и в итоге получают 9 модулей, из которых один имеет 120 LOC, а остальные - в лучшем случае два десятка LOC. Я предпочитаю начать с этого и преобразовать его в пакет и создавать модули только для зверей, которые действительно заслуживают их:источник
Возможно, самый простой вариант - просто поместить эти функции вне класса:
Используя этот метод, функции, которые изменяют или используют внутреннее состояние объекта (имеют побочные эффекты), могут быть сохранены в классе, а многократно используемые служебные функции могут быть перемещены наружу.
Допустим, этот файл называется
dogs.py
. Чтобы использовать их, вы бы позвонилиdogs.barking_sound()
вместоdogs.Dog.barking_sound
.Если вам действительно нужен статический метод, чтобы быть частью класса, вы можете использовать декоратор staticmethod .
источник
Итак, статические методы - это методы, которые можно вызывать без создания объекта класса. Например :-
В приведенном выше примере метод
add
вызывается именем класса, аA
не именем объекта.источник
Статические методы Python могут быть созданы двумя способами.
Использование staticmethod ()
Вывод:
Результат: 25
Использование @staticmethod
Вывод:
Результат: 25
источник
Я сталкиваюсь с этим вопросом время от времени. Пример использования и пример, который мне нравится:
Не имеет смысла создавать объект класса cmath, потому что в объекте cmath нет состояния. Тем не менее, cmath - это набор методов, которые каким-то образом связаны между собой. В моем примере выше все функции в cmath так или иначе действуют на комплексные числа.
источник