Update page 'Day 10 homework - Sloetjes '

xuanyi.wang
2023-04-19 19:17:41 +02:00
parent cd1042785e
commit d06a051cc1
+83
@@ -0,0 +1,83 @@
1. Run the module-inspector script, and fix any problems that prevent it from running.
2. Look at the output. Notice that some of the module names seem similar, and are cached via two different loader methods.
3. Based on what you see from the module-inspector script, modify your answer from question 10 from the day 9 homework, so the similar module names aren't counted multiple times.
```
import sys
import os
from collections import defaultdict
def get_module_stats():
byte_count = 0
dso_count = 0
py_count = 0
module_files = set()
module_dirs = defaultdict(int)
for name, module in sys.modules.items():
if module is None:
continue
filename = getattr(module, '__file__', None)
if not filename:
continue
if filename.endswith('.pyc') or filename.endswith('.pyo'):
byte_count += 1
elif os.path.splitext(filename)[-1] in ('.so', '.dll'):
dso_count += 1
else:
py_count += 1
# check if module filename has been counted already
if filename not in module_files:
module_files.add(filename)
module_dir = os.path.dirname(os.path.abspath(filename))
module_dirs[module_dir] += 1
total_count = byte_count + dso_count + py_count
byte_percent = byte_count / total_count * 100
dso_percent = dso_count / total_count * 100
py_percent = py_count / total_count * 100
return {
'bytecode': {
'count': byte_count,
'percent': byte_percent,
},
'DSO': {
'count': dso_count,
'percent': dso_percent,
},
'python': {
'count': py_count,
'percent': py_percent,
},
'total': total_count,
'module_dirs': module_dirs,
}
def print_module_stats():
stats = get_module_stats()
print(f'Total modules: {stats["total"]}')
print(f'Bytecode modules: {stats["bytecode"]["count"]} ({stats["bytecode"]["percent"]:.2f}%)')
print(f'DSO modules: {stats["DSO"]["count"]} ({stats["DSO"]["percent"]:.2f}%)')
print(f'Python modules: {stats["python"]["count"]} ({stats["python"]["percent"]:.2f}%)')
print('\nModule directory histogram:')
for module_dir, count in sorted(stats['module_dirs'].items(), key=lambda x: x[1], reverse=True):
print(f'{module_dir}: {"*" * count}')
if __name__ == '__main__':
print_module_stats()
```
By using a set called `module_files` to keep track of the filenames of the modules that we have counted so far. Before counting a module, we check if its filename has been counted already. If it has, we skip the module and move on to the next one. This ensures that similar module names are counted only once.
4. Inspect the `__loader__` attribute of each entry in the `sys.modules` dict. Can you find an attribute of `__loader__` which reliably tells you if the loader is source, builtin, or extension?
5. Add `import pandas` to the top of the module-inspector script and re-run it. Notice that many of the pandas modules are not loaded using the `SourceFileLoader`. Can you explain why these modules are different?
Extra credit: use the freeze utility to turn the module-inspector script into a real app.