Специальные методы в Python

Contents
Введение
Пример
__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

Related Articles
OOP in Python
Classes
Methods
class variables
class methods
Static Methods
Inheritance
Special Methods
property decorator
Python
Functions
super()

Search on this site

Subscribe to @aofeed channel for updates

Visit Channel

@aofeed

Feedbak and Questions in Telegram

@aofeedchat