Skip to content

Latest commit

 

History

History
192 lines (142 loc) · 7.34 KB

File metadata and controls

192 lines (142 loc) · 7.34 KB

Функторы

Функторы - это класс в котором определили метод __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

Методы объектов, @classmethod и @staticmethod

Существует 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

В случае если есть класс экземпляры которого мы не хотим создавать самостоятельно(отдельно) то такой класс можно использовать для множественного наследования, такие классы называют примесями.

Классы Mixin - классы которые сами по себе создавать мы не будем, и которые можно использовать для множественного наследования, наделяя их потомков нужным функционалом, то есть просто класс которые дает в реализацию некоторые методов.

Классы примеси следует указывать первыми в дереве наследования, сам по себе примесь ничего не делает, работает только в сочетании с другим классом.