Operator overloading презентация

Embedded types and operator overriding List >>> listFirst = [1, 2, 3] >>> listSecond = [7, 9] >>> print(listFirst + listSecond) [1, 2, 3, 7, 9] Dictionary >>> print(‘a’ in

Слайд 1Operator overloading
+
= ?


Слайд 2Embedded types and operator overriding
List
>>> listFirst = [1, 2, 3]
>>> listSecond

= [7, 9]
>>> print(listFirst + listSecond)
[1, 2, 3, 7, 9]

Dictionary
>>> print(‘a’ in {‘a’: 8, ‘b’ : -3})
True

String
>>> print(‘I love programming! ’ * 2)
I love programming! I love programming!

>>> word = ‘I love ’
>>> print (word + ‘my cat’)
I love my cat

>>> word = ‘aBc’
>>> print (word[1])
B

Слайд 3How it looks inside ?
Operator Overloading is achieved by defining a

special method in the class definition.
The names of these methods starts and ends with double underscores (__). The special method used to overload + operator is called __add__().
Both int class and str class implements __add__() method. The int class version of the __add__() method simply adds two numbers whereas the str class version concatenates the string.

If the expression is for the form x + y
Python interprets it as x.__add__(y).

The version of __add__() method called depends upon the type of x and y. If x and y are int objects then int class version of __add__() is called.
On the other hand, if x and y are list objects then list class version of __add__() method is called.

Слайд 4Overview of frequently used operators


Слайд 5__str__ vs __repr__
Datetime
>>> import datetime
>>> now = datetime.datetime.now()
>>> str(now)
'2018-03-12 11:51:31.766862'
>>>

repr(now)
'datetime.datetime(2018, 3, 12, 11, 51, 31, 766862)'

String
>>> str('Python')
'Python'
>>> repr('Python')
"'Python'"

If __str__ is not defined then str() uses repr()

class StrRepres1:
def __init__(self, num):
self.num = num
>>> ex1 = StrRepres1(5)
>>> print (ex1)
<__main__.StrRepres1 instance at 0x107f53a28>

class StrRepres3:
def __init__(self, num):
self.num = num
def __repr__(self):
return "Repr"+str(self.num)
def __str__(self):
return "Str"+str(self.num)

>>> ex3 = StrRepres3(5)
>>> print (ex3)
Str 5

class StrRepres2:
def __init__(self, num):
self.num = num
def __repr__(self):
return «Repr "+str(self.num)
>>> ex2 = StrRepres2(5)
>>> print (ex2)
Repr 5


Слайд 6Indexing and slicing
Bult-in container(for example, list) support such operations: indexing,

slicing, containing
How it looks inside? - «Magic» methods allows to support such operations
__getitem__(self,index) : index: l[3] or l[1:-1]
__setitem__(self,index,value) : store list: l[3]='a' or l[2:4]=(‘a’,'b','c')
__delitem__(self,index) : delete: del l[3] or del l[1:-1]
__contains__(self,item) : called by the in operator: 'a' in l

class MyList:
storage = [1, 2, 3, 4, 5]
def __str__(self):
return str(self.storage)
def __getitem__(self, index):
if type(index) is int:
print ('Index ' + str(index))
return self.storage[index]
elif type(index) is slice:
print (str(index))
return self.storage[index]
else:
print ('TypeError')
def __setitem__(self, index, value):
if type(index) is int:
print ('Index ' + str(index))
self.storage[index] = value
elif type(index) is slice:
print (str(index))
self.storage[index] = value
else:
print ('TypeError')

>>> examp = MyList() # called func output of func output value
>>> examp[1] # __getitem__ Index 1 #2
>>> examp[-1] # __getitem__ Index -1 #5
>>> examp[1:3] # __getitem__ slice(1, 3, None) #[2, 3]
>>> examp[0:2] = [0, 0] # __setitem__ slice(0, 2, None) #[0, 0, 3, 4, 5]
>>> examp[‘a'] = -9 # __setitem__ TypeError #None


Слайд 7Indexing in action!
(simple way to get mutable string)
class MyString(object):
  def __init__(self,

val):
    self.val = val
def __str__(self):
    return self.val
  def __getitem__(self, index):
    return self.val[index]
  def __setitem__(self, index, val):
    #hack to modify string
    self.val = list(self.val)
    self.val[index] = val
    self.val = ‘’.join(self.val)
def __contains__(self, item):
return item in self.val

>>> st = MyString("Hello Python")
>>> st[6] = ’C’
>>> print (st)
Hello Cython
>>> print (’C’ in st)
True
>>> for letter in st: # call __getitem__ to get letter
>>> print (letter)


Слайд 8Special functions: __iter__ __next__
For creating iterator object you must implement

two special methods: __iter__() and __next__(), collectively called the iterator protocol

class PowTwo:
def __init__(self, max = 0):
self.max = max
def __iter__(self):
self.n = 0
return self
def __next__(self):
if self.n <= self.max:
result = 2 ** self.n
self.n += 1
return result
else:
raise StopIteration

Output

>>> a = PowTwo(4)
>>> i = iter(a)
>>> next(i) #1
>>> next(i) #2
>>> next(i) #4
>>> next(i) #8
>>> next(i) #16
>>> next(i)
Traceback (most recent call last):

StopIteration

Yes, Python allows to implement iterator object using __iter__, __next__
But!
- If you need to check containing of item - overload __contains__ to use in operator
- If you want to iterate your container - use more elegant way of automatically iterating: for loop
>>> for element in my_list:
... print(element)
for loop automatically use method __getitem__ in the range of the size of your container


Слайд 9Operator overloading special functions in Python
Try!
>>> print (2 ** 2

** 3 / 2)

>>> print (21 // 3 ** 2 / 3)

>>> print (not 9 % 4 // 5 <= 0)

>>> print (not 11 // 3 / 2 > 0 and 21 % 13 > 7 * 3 ** 2 or 31 - 6 + 1 < 51 // 19)

Слайд 10Classification of operators
>>> i1 = 7
>>> i2 = 0.3
>>> i1 +=

i2
>>> print(-i1)
-7.3
>>> print (int(i1))
7
>>> print (complex(i1))
(7.3+0j)

Слайд 11Priority of operators (it can be useful for you)
max
min


Слайд 12Reflected operators
Arithmetic(+ - * / // % ** > |

& ^) operators have reflected form:
it starts from letter r (r means reflected).
For example:
__add__(self, other) - arithmetic
__radd__(self, other) - reflected
Example:

the operands are of different types
__radd__ is only called if the left operand does not support the corresponding operation __add__ (in our case, built-in type (int) doesn’t support __add__ for user type)
__add__ method of built-in type returns NotImplemented value
If user type doesn’t support __radd__ - Python interpreter raises TypeError exception


Слайд 13__call__ and operator ( )
Magic func __call__(self[, args…]) allows objects to

behave as functions
At the same time it is a way to overload operator ( )

class Changeable:
def __init__(self, color):
self.color = color
def __call__(self, newcolor):
self.color = newcolor
def __str__(self):
return "%s" % self.color
 
>>> changeable = Changeable(«green") #call __init__
>>> changeable(«red") #call __call__
>>> print (changeable) #call __str__
red

behavior of __call__ method is similar to the closure

f1(word):
def f2():
print(‘hello ', word)
return f2
cb3 = f1('world')
cb3() #hello world


Слайд 14__setAttr__ and __getAttr__
Assignment = to a name is a fundamental feature

of Python and no hooks have been provided to change its behavior.
= is not operator in Python!

Alternative ways:
__init__ method - define special initialization for your object
>>> obj = Obj( ) #call __init__
2. overload methods: __setattr__ and __getattr__ for initialization and control access to attributes

class ExampleAccess:
def __init__(self, number):
self.number = number # call __setattr__
def __setattr__(self, key, value):
if key == ‘number':
# ! use special func __dict__[key] for initialization to avoid recursion CRASH !
self.__dict__[key] = value * 2
else:
raise AttributeError()

>>> ex = ExampleAccess(2) #call __init__
>>> print (ex.number) #4
>>> ex.number = 3 #call __setattr__
>>> print (ex.number) #6


Слайд 15
'is' vs '=='
1. operator == checks the equality of the values

​​of two objects
2. is operator checks the identity of the objects themselves. It is used to make sure that variables references to the same object in memory

For performance Python caches short strings and small integers, so there are possible problem with strings:
>>> str1 = 'hello'
>>> str2 = 'hello'
>>> str1 == str2
True
>>> str1 is str2
True

For right work with user classes you need to overload == operator.
By default is operator compares references in user classes.

Слайд 16Inheritance and operators
class Base:
def __init__(self, number):

self.number = number
def __add__(self, other):
return Base(self.number + other.number)

class SonA(Base):
def fA(self):
print ('A')

class SonB(Base):
def fB(self):
print (‘B’)

>>> a = SonA(3)
>>> b = SonB(5)
>>> print (a + b)
8

Overloaded operators in the base class are inherited.


Слайд 17Operator overloading is here to help you
Operator overloading allows user defined

type to intercept Python built-in operations
All Python expression operator like ‘+’, ‘-’ can be overloaded
Built-in operators such as printing, attribute access can be overloaded
Python provides specially named method to be used in class to support operator overloading

It allows users to decide how a language built-in operation act on user defined type

Слайд 18Problems to solve
- Think about operator overloading and create your user

class. Overload such operators that will be relevant in work with its instances

-Add operator overloading in own project if it’s necessary and reasonable

Обратная связь

Если не удалось найти и скачать презентацию, Вы можете заказать его на нашем сайте. Мы постараемся найти нужный Вам материал и отправим по электронной почте. Не стесняйтесь обращаться к нам, если у вас возникли вопросы или пожелания:

Email: Нажмите что бы посмотреть 

Что такое ThePresentation.ru?

Это сайт презентаций, докладов, проектов, шаблонов в формате PowerPoint. Мы помогаем школьникам, студентам, учителям, преподавателям хранить и обмениваться учебными материалами с другими пользователями.


Для правообладателей

Яндекс.Метрика