Функторы - это класс в котором определили метод
__call__(self, *args, **kargs) этот метод будет срабатывать
когда объект класс пытаются вызвать как метод.
class StripChars:
"""Класс функтор, удаляет из строки все не нужные символы"""
def __init__(self, chars):
self.__chars = chars
def __call__(self, *args, **kwargs):
if not isinstance(args[0], str):
raise ValueError("Аргумент должен быть строкой")
return args[0].strip(self.__chars)
sc = StripChars('!')
print(sc('Hello World!'))
# Вывод
# Hello WorldСуществует 3 метода, это может быть обычный динамический метод,
который вызывается у объекта и имеет один обязательный метод self
Также помимо них, существует 2 типа других методов, которые задаются при помоях декораторов.
@classmethod - метод с таким декоратором требует получение аргумента
cls который содержит в себе ссылку на этот класс, этого же можно
добиться при помощи указания названия класса.
@classmethod
def class_meythod(cls):
return cls.STATIC_NAME@staticmethod - обычный декоратор для метода, он не требует никаких
специальных аргументов, и может обращаться к значениям класса при
помощи указания названия этого класса.
@staticmethod
def static_method():
return Point.STATIC_NAMEПо существу это выглядит так, @classmethod - используется для
методов которые будут работать с данными класса, а @staticmethod
используется для операций тематически связанных к этим классом,
однако в любом их них на самом деле можно делать что угодно,
и работать с любыми объектами класса, если передать объект класса
в эти методы, чтобы использовать его как заменитель self
Создаются при помощи декоратора @staticmethod и также метод
более не требует использования параметра self
Пример статического метода:
@staticmethod
def getCounter():
return Point.__countПо скольку у метода более нет аргумента self мы более не можем
оперировать к объектам, только к статике класса.
Создадим класс, который будут при помощи статического атрибута считать количество экземпляров самого класса.
class Point:
__count = 0
def __init__(self, x, y):
Point.__count += 1
self.x = x
self.y = y
@staticmethod
def getCounter():
return Point.__count
pt1 = Point(1, 2)
pt2 = Point(10, 20)
def newGetCounter():
return 55
pt1.getCounter = newGetCounter
print(pt1.getCounter())
print(Point.getCounter())
# Вывод
# 55
# 2Также можно увидеть на этом примере, что можно переопределить метод из вне, внеся в него значение другого метода.
def newGetCounter():
return 55
pt1.getCounter = newGetCounterСделав это мы переопределили метод класса на другой.
Перегрузка методов - Выполнять разный функционал в зависимости от количества переданных аргументов.
Если в других языках типа C# это подразумевает еще и создание нового
одноименного метода, то в Питоне это делается просто путем условий.
К примеру так:
def setCoords(self, start:Point, end:Point=None):
if end is None:
if start.check_int():
self._start = start
else:
print("Координаты должны быть целочисленными")
else:
if start.check_int() and end.check_int():
Point.set_coord(self, start, end)
else:
print("Координаты должны быть целочисленными")Таким образом мы теперь можем вызывать метод как с 2, так и с 1 арг.
Абстрактные методы - методы которые должны быть обязательно реализованы в дочерних классах.
Сделать это можно путем вызова исключения, метод будет всегда давать исключение, до тех пор пока его не переопределят, таким образом мы заставляем переопределить этот метод в дочерних классах.
Пример реализации:
def drawLine(self):
raise NotImplementedError(
"В дочернем классе должен быть переопред метод drawLine()"
)В случае если есть класс экземпляры которого мы не хотим создавать самостоятельно(отдельно) то такой класс можно использовать для множественного наследования, такие классы называют примесями.
Классы Mixin - классы которые сами по себе создавать мы не
будем, и которые можно использовать для множественного наследования,
наделяя их потомков нужным функционалом, то есть просто класс
которые дает в реализацию некоторые методов.
Классы примеси следует указывать первыми в дереве наследования, сам по себе примесь ничего не делает, работает только в сочетании с другим классом.