The other day I learned about 100 Days Of Code, which was popular on Twitter for a while. The purpose of this article is to keep a record and output how much I, as a beginner, can grow through 100 days of study. I think there are many mistakes and difficult to read. I would appreciate it if you could point out!
--Progress: Pages 61-64 --Chapter 3: Classes and Inheritance ――I will write down what I often forget or didn't know about what I learned today.
Python has many built-in APIs that allow you to customize its behavior by passing functions. Such a mechanism is called ** hook **, and the API calls back the code during execution. For example, if you want to customize the defaultdict class, this data structure allows you to give a function that will be called each time the key is not found. Define a hook that logs if the key is not found and returns 0 as the default value as follows:
def log_missing():
print('Key added')
return 0
Log_missing is performed with the initial dictionary and additional datasets.
from collections import defaultdict
current = {'green': 10, 'blue': 2}
increments = [
('red', 3),
('blue', 15),
('orange', 8)
]
result = defaultdict(log_missing, current)
print('Before: ', dict(result))
for key, amount in increments:
result[key] += amount #log every time result is entered_missing is called
print('After: ', dict(result))
Output result
Before: {'green': 10, 'blue': 2}
Key added
Key added
After: {'green': 10, 'blue': 17, 'red': 3, 'orange': 8}
Define a helper function that counts the total number of keys that cannot find the hook with the default value passed to defaultdict as follows.
from collections import defaultdict
def increment_with_report(current, increments):
added_count = 0
def missing():
nonlocal added_count #Closure condition
added_count += 1 #Increase by 1 each time it is called
return 0
result = defaultdict(missing, current)
for key, amount in increments:
result[key] += amount
return result, added_count
current = {'green': 10, 'blue': 2}
increments = [
('red', 3),
('blue', 15),
('orange', 8)
]
result, count = increment_with_report(current, increments)
print(count)
Output result
2
Another way is to define an encapsulated class.
from collections import defaultdict
class CountMissing(object):
def __init__(self):
self.added = 0
def missing(self):
self.added += 1
return 0
current = {'green': 10, 'blue': 2}
increments = [
('red', 3),
('blue', 15),
('orange', 8)
]
counter = CountMissing()
result = defaultdict(counter.missing, current)
for key, amount in increments:
result[key] += amount
print(counter.added)
Output result
2
It is difficult to understand what the CountMissng class is intended for until defaultdict is called. To get rid of this esotericity, Python can define a special method call. call allows the object to be called like a function.
from collections import defaultdict
class BetterCountMissing(object):
def __init__(self):
self.added = 0
def __call__(self):
self.added += 1
return 0
current = {'green': 10, 'blue': 2}
increments = [
('red', 3),
('blue', 15),
('orange', 8)
]
counter = BetterCountMissing()
result = defaultdict(counter, current) # __call__Allows you to pass a class directly instead of a method
for key, amount in increments:
result[key] += amount
print(counter.added)
Output result
2
Recommended Posts