Существует порядка 120 магических методов, но не все они используются, рассмотрим самые частые из них.
Магические методы еще называют dunder-методами.
__new__(cls, arg)- Истинный конструктор класса, метод__init__называют конструктором по привычке.
Он является методом класса, то есть должен быть статическим и
использовать для этого декоратор @classmethod но этот метод
обрабатывается особенным образом, так что декоратор для статичности
он не использует.
Этот должен возвращать экземпляр класса, то есть должен создавать
обьект и возвращать его, именно этот обьект и передается в
метод __init__(self) как первый аргумент self
Поскольку метод __init__() ничего не может возвращать получается
что обьект создается в методе __new__ а метод __init__ просто
инициализирует переменный обьекта.
-
__init__(self)- Метод конструктор(как его обычно называют), используется для инициализации динамических атрибутов класса, запускается автоматически при создании обьекта.Этому методу запрещено возвращать что либо кроме
Noneчто является стандартным поведением методов и функций, любая функция что-то возвращает, и если это не переопределено то возвращаетNone -
__str(self)__- Должен возвращать при помощи ключевого словаreturnстроку описывающую класс, этот метод вызывается автоматически когда обьект вызывается при помощи функцииprint() -
__repr(self)__- Должен возвращать строковое представление класса, при помощи оператораreturn. Используется автоматически когда на класс используется функцияrepr()помним что сама по себе функцияrepr()не выводит строку, а только ее возвращает, так что для этого следует использовать комбинациюprint(repr(obj)) -
__len__(self)- Используется автоматически при использовании методаlen()на обьект, этот метод обязан возвращать целочисленное значение типаintпри помощиreturn
Пример использования магических методов __init__, __str__,
__repr__, __len__():
class MyClass():
def __init__(self, name, my_list):
self.name = name
self.my_list = my_list
def __str__(self):
return "Метод __str__"
def __repr__(self):
return "Метод __repr__"
def __len__(self):
return len(self.my_list)
x = MyClass('Антонио', [1,2,3,4])
print(x)
print(repr(x))
print(len(x))
# Вывод
# Метод __str__
# Метод __repr__
# 4__del__(self)- Метод не должен ничего возвращать, отрабатывает при уничтожении последней ссылки на обьект.
def __del__(self):
"""
__del__ деструктор класса, вызывается при уничтожении
последней ссылки на обьект этого класса.
"""
print("Отработал метод __del__ Обьект класса MyClass уничтожен")__abs__(self)отрабатывает при использовании на объект функцииabs()для получения значения по модулю, может возвращать как число, так и список.
Возвращать что-либо необязательно.
__hash(self)__отрабатывает при использовании функции хеширования на объект. Если использовать функциюhash()на обычное целое число ответом будет самом же это число, но другие данныеfloatилиstr... будут преобразованы в целое число.
Эти методы определяют поведения объектов когда на них используется операторы сравнения.
Для сравнения эти методы принимают 2 параметра, self что представляет
сам объект, и other что представляет другой объект.
-
__eq__(self, other)- поведения при== -
__cmp__(self, other)- этот метод определят поведение для всех операторов, этим объектом можно определить поведение всех объектов и всех их операторов. -
__ne__(self, other)- Определяет поведение оператора неравенства!= -
__lt__(self, other)- Определяет поведение оператора меньше< -
__gt__(self, other)- Определяет поведение оператора больше> -
__le__(self, other)- Определяет поведение оператора меньше или равно<= -
__ge__(self, other)- Определяет поведение оператора больше или равно>=
Примеры поведения, на этом примере можно увидеть как работает метод для
переопределения операторов сравнения, суть такова, метод принимает
2 параметра self и other где есть собственный и дополнительный
объект, а далее мы сами можем переопределить поведение, возвращаем
либо True, либо False это можно увидеть на след примере:
class Test():
def __init__(self, name):
self.name = name
def __eq__(self, other):
print(f"self = {len(self.name)}", self)
print("other = ", other)
if len(self.name) == other:
return True
return False
x = Test('Names')
print(x==5)
# Вывод
# self = 5 <__main__.Test object at 0x7f5ad9ddc208>
# other = 5
# True-
__getattr__(self, name)Вызывается при попытке вызова метода которого не существует. -
__setattr__(self, name, value)Позволяет установить новое значение для атрибута, существует он или нет. -
__delattr__(self, name) -
__getattribute__(self, name)
Метод отрабатывает когда мы обращаемся к объекту как к элементу списка, по индексу, примеру так:
from string import ascii_letters
class MyContainer(object):
def __getitem__(self, key):
print('key = ', key)
return ascii_letters[key]
my_container = MyContainer()
print(my_container[0]) # выведет a
print(my_container[16]) # выведет q
print(my_container[:]) # выведет все элементы
# Вывод
# key = 0
# a
#
# key = 16
# q
#
# key = slice(None, None, None)
# abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZПеременная из ascii_letters содержит в себе все буквы алфавита.
Замена байт-кода одной функции, байт-кодом другой функции, у объектов в
питоне есть атрибут __code__ заменяя код одного объекта другим мы
полностью заменяем код объекта.
def func1(a, b):
print(a * b)
def testing():
pass
print(func1)
print(func1.__code__)
testing.__code__ = func1.__code__
testing(2, 5)
# Вывод
# <function func4.<locals>.func1 at 0x7f70513739d8>
# <code object func1 at 0x7f70513d5e40, file "./1.py", line 71>
# 10При использовании функции hash() на данные мы по сути вызываем метод
__hash__() этого объекта, ибо все данные в питоне являются объектами.
У объектов можно определить метод __hash()__ которая будет отрабатывать
при использовании функции hash() на этот объект, так образом можно самим
определять свои собственные функции для хеширования.