OOP technicalities¶
There is much to say about object oriented programming, here the focus is only made on few technical points of python objects useful later in the course.
Iterator¶
An iterator is an object with a __next__ method.
It raises an StopIteration exception when there is no ‘next’ item.
Iterable¶
An iterable is an object with an __iter__ method which returns an iterator.
It is a python object which can be seamlessly iterated over.
Callable¶
An object can be made callable if a __call__ method is defined.
It useful when you need a function with a state.
Class attributes¶
Some attributes can be defined directly under the class declaration.
These attributes are shares between all instances of the class.
Note
Careful! several very popular libraries use some dark magic to automatically define from class attributes
the instance attributes for every instance. dataclass, attrs, django, pydantic etc.
1import random
2
3
4class RandomTraversalIterator:
5 def __init__(self, items: list[int]) -> None:
6 self.items = items
7 self.indexes = list(range(len(items)))
8 random.shuffle(self.indexes)
9
10 def __next__(self) -> int:
11 if self.indexes:
12 return self.items[self.indexes.pop()]
13 raise StopIteration
14
15
16class RandomTraversalIterable:
17 def __init__(self, items: list[int]) -> None:
18 self.items = items
19
20 def __iter__(self):
21 return RandomTraversalIterator(self.items)
22
23
24class CheckAnswerMultipleGuess:
25 def __init__(self, question: str, correct_answer: int, nb_trial: int) -> None:
26 self.question = question
27 self.correct_answer = correct_answer
28 self.remaining = nb_trial
29 print(question)
30
31 def __call__(self, answer: int) -> str:
32 if self.remaining == 0:
33 return "no more guess"
34 if answer == self.correct_answer:
35 return "correct"
36 self.remaining -= 1
37 return f"incorrect, remains {self.remaining} guess(es)"
38
39
40def show_iterator():
41 numbers: list[int] = [10, 11, 12]
42 iterator = RandomTraversalIterator(numbers)
43 try:
44 print(next(iterator))
45 print(next(iterator))
46 print(next(iterator))
47 print(next(iterator))
48 except StopIteration:
49 print("no more item")
50
51
52def show_iterable():
53 numbers: list[int] = [20, 21, 22]
54 for item in RandomTraversalIterable(numbers):
55 print(item)
56
57
58def show_callable():
59 check = CheckAnswerMultipleGuess(
60 "guess number between 0-100", correct_answer=42, nb_trial=3
61 )
62 print(check(41))
63 print(check(40))
64 print(check(42))
65 print(check(43))
66 print(check(44))
67
68
69if __name__ == "__main__":
70 show_iterator()
71 show_iterable()
72 show_callable()