Специальные методы в Python
Введение | |
Пример | |
__repr__() | |
__str__() | |
__add__() | |
__repr__() из datetime | |
__str__() из datetime | |
__add__() из datetime | |
Похожие статьи |
Введение
Это продолжение статьи
«Классы»
из раздела
«ООП в Python»
.
Для лучшего понимания этого материала пригодятся знания из следующих статей:
Методы
,
Класс методы
,
Статические методы
,
super()
,
Декораторы
,
isinstance()
Специальные методы всегда окружены двумя нижними подчёркиваниями слева и справа.
Мы уже сталкивались со специальным методом
__init__()
В англоязычном сообществе принято произносить такое написание как “dunder init”
Пример
Создадим класс Employee и посмотрим что покажут методы repr и str
class Employee: num_of_emps = 0 raise_amount = 1.04 def __init__(self, first, last, pay): self.first = first self.last = last self.pay = pay self.email = first + '.' + last + '@kaspersky.com' Employee.num_of_emps += 1 def fullname(self): return f'{self.first} {self.last}' def apply_raise(self): self.pay = int(self.pay * self.raise_amount) emp_1 = Employee("Eugene", "Kaspersky", 50000) print(emp_1) print(repr(emp_1)) print(str(emp_1)) # Same as # print(emp_1.__repr__()) # print(emp_1.__str__())
python special_methods.py
<__main__.Employee object at 0x7f486bee5fd0> <__main__.Employee object at 0x7f486bee5fd0> <__main__.Employee object at 0x7f486bee5fd0>
Как видно из вывод выше методы работают, выдают одну и ту же информацию о том, что это объект класса Employee который находится по данному адресу.
__repr__()
Реализуем метод __repr__()
def __repr__(self): return f"Employee({self.first}, {self.last}, {self.pay})"
python special_methods.py
Employee(Eugene, Kaspersky, 50000) Employee(Eugene, Kaspersky, 50000) Employee(Eugene, Kaspersky, 50000)
Теперь информация соответсвует тому, что мы определили в методе, причем снова везде одно и то же.
__str__()
Добавим метод __str__()
def __repr__(self): return f"Employee({self.first}, {self.last}, {self.pay})" def __str__(self): return f"{self.fullname()} - {self.email}"
python special_methods.py
Eugene Kaspersky - Eugene.Kaspersky@kaspersky.com Employee(Eugene, Kaspersky, 50000) Eugene Kaspersky - Eugene.Kaspersky@kaspersky.com
Вывод метода __repr__() никак не изменился, а print(emp_1) теперь повторяет на за __repr__() а за __str__()
__add__()
Рассмотрим метод __add__()
print(1+2) print(int.__add__(1, 2)) print("a" + "b") print(str.__add__("a", "b"))
python special_methods.py
3 3 ab ab
Если сходу попробовать сложить два объекта класса Employee получится TypeError
Можно сделать свой __add__() для любого класса. В классе Employee можно, например, складывать заплаты сотрудников с помощью следующего метода:
def __add__(self, other): return self.pay + other.pay emp_1 = Employee("Eugene", "Kaspersky", 330) emp_2 = Employee("Andrei", "Olegovich", 330) print(emp_1 + emp_2)
python special_methods.py
660
__repr__() из datetime
Изучим реальные примеры применения специальных методов. Для этого
рассмотрим библиотеку
datetime
(
github
)
Начнём с __repr__()
def __repr__(self): """Convert to formal string, for repr(). >>> dt = datetime(2010, 1, 1) >>> repr(dt) 'datetime.datetime(2010, 1, 1, 0, 0)' >>> dt = datetime(2010, 1, 1, tzinfo=timezone.utc) >>> repr(dt) 'datetime.datetime(2010, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)' """ return "%s.%s(%d, %d, %d)" % (self.__class__.__module__, self.__class__.__qualname__, self._year, self._month, self._day) # XXX These shouldn't depend on time.localtime(), because that # clips the usable dates to [1970 .. 2038). At least ctime() is # easily done without using strftime() -- that's better too because # strftime("%c", ...) is locale specific.
__str__() из datetime
Рассмотрим специальные метод
__str__()
и библиотеки
datetime
(
github
)
Метод __str__() просто повторяет метод isoformat()
def isoformat(self): """Return the date formatted according to ISO. This is 'YYYY-MM-DD'. References: - http://www.w3.org/TR/NOTE-datetime - http://www.cl.cam.ac.uk/~mgk25/iso-time.html """ return "%04d-%02d-%02d" % (self._year, self._month, self._day) __str__ = isoformat
__add__() из datetime
Рассмотрим специальные метод __add__() и библиотеки datetime ( github )
def __add__(self, other): if isinstance(other, timedelta): # for CPython compatibility, we cannot use # our __class__ here, but need a real timedelta return timedelta(self._days + other._days, self._seconds + other._seconds, self._microseconds + other._microseconds) return NotImplemented
OOP in Python | |
Classes | |
Methods | |
class variables | |
class methods | |
Static Methods | |
Inheritance | |
Special Methods | |
property decorator | |
Python | |
Functions | |
super() |