## Slide 1

### Slide 1 text

DEMYSTIFYING PYTHON MAGIC __METHODS__ Naren

## Slide 2

### Slide 2 text

WHO AM I ? Naren Software Consultant @DudeWhoCode    Cycling | Travelling | Blogging

## Slide 3

### Slide 3 text

MAGIC METHODS • What ? • Why ? • How ?

## Slide 4

### Slide 4 text

MOST FAMILIAR MAGIC METHOD ?

## Slide 5

### Slide 5 text

MOST FAMILIAR MAGIC METHOD ? __init__( )

## Slide 6

### Slide 6 text

WHAT? • Pre-deﬁned methods used to enrich your classes • Also known as • Special methods • Dunder methods (Double underscores) • Lets you to emulate the builtin types

## Slide 7

### Slide 7 text

YOU KNOW… In [1]: l = ['a', 'b', 'c', ‘d'] In [2]: l.index('b') Out[2]: 1 In [3]: t = ('a', 'b', 'c', 'd',) In [4]: t.index('b') Out[4]: 1 In [5]: len(l) Out[5]: 4 In [6]: len(t) Out[6]: 4

## Slide 8

### Slide 8 text

FROM PYTHON FAQ… Why does Python use methods for some functionality (e.g. list.index()) but functions for other (e.g. len(list))? • The major reason is history. • Functions were used for those operations that were generic for a group of types and which were intended to work even for objects that didn’t have methods at all (e.g. tuples). It is also convenient to have a function that can readily be applied to an amorphous collection of objects when you use the functional features of Python (map(), apply() et al). • In fact, implementing len(), max(), min() as a built-in function is actually less code than implementing them as methods for each type. • It’s too late to make such fundamental changes now. The functions have to remain to avoid massive code breakage.

HOW ?

DEMO

No content

## Slide 12

### Slide 12 text

__init__ __new__ __del__ __hash__ __slots__ __dict__ __instancecheck__ __subclasscheck__ __subclasshook__ __enter__ __exit__ __copy__ __deepcopy__ __getstate__ __reduce__ __reduce_ex__ __getnewargs__ __getattr__ __getattribute__ __setattr__ __delattr__ __dir__ __add__ __sub__ __mul__ __ﬂoordiv__ __truediv__ __mod__ __pow__ __lshift__ __rshift__ __and__ __xor__ __or__ __iadd__ __isub__ __imul__ __idiv__ __iﬂoordiv__ __imod__ __ipow__ __ilshift__ __irshift__ __iand__ __ixor__ __ior__ __neg__ __pos__ __abs__ __invert__ __complex__ __int__    __long__ __ﬂoat__ __oct__ __hex__ __lt__ __le__ __eq__ __ne__ __ge__ __gt__

## Slide 13

### Slide 13 text

BINARY OPERATORS + object.__add__(self, other) - object.__sub__(self, other) * object.__mul__(self, other) // object.__ﬂoordiv__(self, other) / object.__truediv__(self, other) % object.__mod__(self, other) ** object.__pow__(self, other[, modulo]) << object.__lshift__(self, other)

## Slide 14

### Slide 14 text

BINARY OPERATORS (CONTD.) << object.__lshift__(self, other) >> object.__rshift__(self, other) & object.__and__(self, other) ^ object.__xor__(self, other) | object.__or__(self, other)

## Slide 15

### Slide 15 text

EXTENDED OPERATORS += object.__iadd__(self, other) -= object.__isub__(self, other) *= object.__imul__(self, other) /= object.__idiv__(self, other) //= object.__iﬂoordiv__(self, other) %= object.__imod__(self, other) <<=object.__ilshift__(self, other) >>=object.__irshift__(self, other)

## Slide 16

### Slide 16 text

EXTENDED OPERATORS (CONTD.) |=object.__ior__(self, other) &= object.__iand__(self, other) ^= object.__ixor__(self, other) **= object.__ipow__(self, other[, modulo])

## Slide 17

### Slide 17 text

UNARY OPERATORS - object.__neg__(self) + object.__pos__(self) abs() object.__abs__(self) ~ object.__invert__(self) complex() object.__complex__(self) int() object.__int__(self) long()object.__long__(self) ﬂoat() object.__ﬂoat__(self) oct() object.__oct__(self) hex() object.__hex__(self)

## Slide 18

### Slide 18 text

COMPARISON OPERATORS < object.__lt__(self, other) <= object.__le__(self, other) == object.__eq__(self, other) !=object.__ne__(self, other) >= object.__ge__(self, other) > object.__gt__(self, other)

## Slide 19

### Slide 19 text

⚠ CAUTION ⚠ • Over use of magic methods makes your code complex to understand

## Slide 20

### Slide 20 text

THANK YOU, NAREN @DudeWhoCode Slides:  www.dudewho.codes/talks