Альтернативы статическим методам Python
ООП на Python static метод python, статический метод python, статический метод python пример
Кроме возможности пометить метод, как специальный, существуют и другие приемы, которые можно попробовать. Если для доступа к атрибутам класса требуется вызывать функции, которые не принимают ссылку на экземпляр, самая простая мысль, которая приходит в голову, сделать метод обычной функцией, а не методом класса.
При таком способе функции не требуется передавать экземпляр класса. Например, следующая версия spam.py действует одинаково в Python 3 и 2.7(правда, в этой версии инструкция print отображает лишние круглые скобки при выполнении под управлением Python 2.7):
def printNumInstancesNow():
print("Number of instances created: ", Spam.numInstances)
class Spam:
numInstances = 0
def __init__(self):
Spam.numInstances += 1
>>> from spam import Spam, printNumInstancesNow
>>> a = Spam()
>>> b = Spam()
>>> c = Spam()
>>> d = Spam()
>>> printNumInstancesNow() # Но функция может находиться слишком далеко от определения класса и не может адаптироваться в подклассах
Number of instances created: 4
>>> Spam.numInstances
4
Поскольку имя класса доступно простой функции в виде глобальной переменной, все работает прекрасно. Кроме того, обратите внимание, что имя самой функции также является глобальным, но только в этом единственном модуле - оно не будет конфликтовать с именами в других модулях программы.
До появления статических методов в Python такой способ был единственным. Поскольку в языке Python уже имеются модули, которые играют роль инструмента разделения пространства имен, можно было бы утверждать, что обычно нет никакой необходимости упаковывать функции и классы, если они не реализуют функциональность объектов. Простые функции внутри модуля, как в данном примере, способны решать большую часть задач, которые возлагаются на методы класса, не имеющие аргумента self, и уже связаны с классом, потому что располагаются в том же самом модуле.
К сожалению, такой подход далек от идеала. С одной стороны, в область видимости файла добавляется лишнее имя, которое используется для работы с единственным классом. С другой стороны - функция не имеет тесной связи с классом. Фактически определение функции может находиться за сотни строк от определения класса.
Но самое неприятное, пожалуй, состоит в том, что простые функции, как в данном примере, не могут адаптироваться в подклассах, потому что они располагаются за пределами пространства имен класса: подклассы не могут непосредственно переопределять или замещать такие функции.
Кстати, в следующих уроках также поговорим про взаимодействие языка Python с движком WordPress. Вы наверное уже знаете, что WordPress является популярнейшим движком на сегодняшний день. Также очень популярен является шаблон Lawyer Pro для WordPress. Скачать премиум шаблоны сможете на cmsdude.org.
Мы могли бы попытаться обеспечить работоспособность этого примера в обеих версиях интерпретатора, используя обычный метод, и всегда вызывать его через(или передавать вручную) экземпляр:
class Spam:
numInstances = 0
def __init__(self):
Spam.numInstances += 1
def printNumInstances(self):
print("Number of instances created: ", Spam.numInstances)
>>> from spam import Spam
>>> a, b, c, d = Spam(), Spam(), Spam(), Spam()
>>> a.printNumInstances()
Number of instances created: 4
>>> Spam.printNumInstances(a)
Number of instances created: 4
>>> Spam().printNumInstances() # Эта попытка извлечь счетчик изменяет его!
Number of instances created: 5
К сожалению, как уже упоминалось выше, такой подход полностью непригоден в случае отсутствия доступного экземпляра, а создание нового экземпляра изменяет данные класса, как видно в последней строке этого примера. Лучшее решение заключается в том, чтобы каким-либо способом пометить метод класса, который не требует передавать ему ссылку на экземпляр. Как это сделать, мы поясним в следующих уроках.
- Слоты и обобщенные инструмены в Python
- Наследование. Объектно-ориентированное программирование в Python
- Объектно-ориентированное программирование. Определение класса и создание экземпляра класса в Python
- Классы нового стиля. ООП в Python
- Объектно-ориентированное программирование. Методы __init__() и __del__() в Python
- Статические методы и методы класса
- Множественное наследование в Python